Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 9 years ago.
Improve this question
I am working with set of points, and my goal is to add 4 vectors together and calculate the resultant between start and end point,
Since I already prepared the code to do the above part which seems to be working fine but am not to sure about it.
Anyway the real reason I am posting this question is to do with the resultant direction and angle.
I find it hard to either understand the concept of finding resultant angle and direction as well as PROGRAMMING wise.
Consider this scenario....Image
1st add vectors "Head 2 Tail"
From what I have learned about vector addition is to subtract x2 - x1, y2 -y1 this will dive me the misplacement difference and do the same calculation for all the points from A-E
To get the resultant I square root all the points x to power of 2 and add all the y position to power of 2.
This ideology seem to work fine.....
But the QUESTION here is how do i get the angle and direction of that resultant....?
the code I use to calculate resultant:
double Pta;
double Ptb;
Point vect;
float R1, R2;
float resultant;
for(vector<Point>::iterator iter_a = Left_Arm_xy.begin()+1; iter_a != Left_Arm_xy.end(); ++iter_a)
{
if(center.y <= 240)
{
vect.x = iter_a->x - (iter_a -1)->x;
vect.y = iter_a->y - (iter_a -1)->y;
vect_add.push_back(Point(vect.x,vect.y));
for(vector<Point>::iterator iter_v = vect_add.begin(); iter_v - vect_add.begin() + 4 < vect_add.size(); iter_v+=4)
{
R1 = iter_v->x + (iter_v +1)->x + (iter_v +2)->x + (iter_v +3)->x;
R2 = iter_v->y + (iter_v +1)->y + (iter_v +2)->y + (iter_v +3)->y;
resultant = sqrt(pow(R1,2) + pow(R2,2));
}
}
Consider this..............
Ok lets consider Points A[2,4], B[4,8], C[10,12], To add this vectors i add vectors/points I subtract point B x4 - A x2 and point B y8 - A y4 and point C x10 - B x4 and point C y12 - B y8 this will give me the the displacements between points....Now to get the Resultant i add all the Points X's and Y's x's 2+4+10 = 16 y's 4+8+12 = 24, Next i would square root 16 ^2 + 24^2 = 28.84. So based on these calculations where resultant is a number not and x and y value how can i get the direction and angle....?
It is a simple summation of vectors.
(x, y) = (x1, y1) + (x2, y2) + ... = (x1+x2+..., y1+y2+...)
When you have the final vector, it's angle is found by using
tan(angle) = y/x
The angle between two vectors is generally defined as:
Angle = arccos( DotProduct(v1, v2) / ( Length(v1) * Length(v2) ) );
The direction is simply subtraction of the two vectors:
Direction = v2 - v1;
Usually, you have to normalize this to get a unit vector:
Len = SquareRoot( direction.x * direction.x + direction.y * direction.y );
Direction.x /= Len;
Direction.y /= Len;
Thus, you'll have a unit direction vector and the angle of the vector.
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
Currently I was trying to solve a problem with the condition below:
1. giving an elliptic curve y^2 = x^3 + ax + b
2. the user will input a, b and two points that exactly on the curve.
To put it simply, what I really need to do is make a secant line of the graph with the two points P and Q and try to check that if there is any point of intersection existing. If it exists, get the x and y of this point. I'm so struggled to solve this problem. Could someone give me some hints?
I'd homogenize this to x^3 + axz^2 + bz^3 - y^2z = 0 and points P = [Px : Py : Pz] and Q = [Qx : Qy : Qz]. Then any point R = λP + μQ with (λ, μ) ≠ (0, 0) lies on the line spanned by P and Q. If you wanted to avoid homogenizations, you'd require λ+μ=1 but that usually leads to divisions I'd rather avoid until the very end.
Plug the resulting coordinates of R into the homogenized equation of the elliptic curve, and you obtain a homogeneous cubic equation in λ and μ, i.e. something like
αλ³ + βλ²μ + γλμ² + δμ³ = 0
with the α, β, γ and δ depending on your a, b, P, Q. For μ=0 you get a coordinate vector which is a multiple of P, and as homogeneous coordinates identify multiples, you get point P itself, which lies on the curve. So μ=0 must satisfy the equation, hence you know α=0 even before you compute it. Likewise λ=0 represents Q so δ=0 if that point lies on the curve. You are left with
(βλ + γμ)λμ = 0
The trailing two factors encode the two known intersections I just mentioned. The parenthesis is the third intersection, the one you need. Now simply pick λ=γ and μ=−β to obtain a simple expression for the third point of intersection.
If you want to dehomogenize at the end, simply divide the first two coordinates of the resulting homogeneous coordinate vector by the third.
If I didn't mess up my sympy computation, you have
β = 3*Px^2*Qx + 2*Px*Pz*Qz*a - Py^2*Qz - 2*Py*Pz*Qy + Pz^2*Qx*a + 3*Pz^2*Qz*b
γ = 3*Px*Qx^2 + 2*Pz*Qx*Qz*a - Pz*Qy^2 - 2*Py*Qy*Qz + Px*Qz^2*a + 3*Pz*Qz^2*b
Which is expectedly very symmetric in P and Q. So essentially you just need a single function, and then you get β=f(P,Q) and γ=f(Q,P).
In C++ and with the whole homogenization / dehomogenization in place:
inline double f(double Px, double Py, double Qx, double Qy, double a, double b) {
return 3*Px*Px*Qx + 2*Px*a - Py*Py - 2*Py*Qy + Qx*a + 3*b;
}
std::pair<double, double> third_intersection(double Px, double Py, double Qx, double Qy, double a, double b) {
double beta = f(Px, Py, Qx, Qy, a, b);
double gamma = f(Qx, Qy, Px, Py, a, b);
double denominator = gamma - beta; // Might be zero if line PQ is an asymptote!
double x = (gamma*Px - beta*Qx) / denominator;
double y = (gamma*Py - beta*Qy) / denominator;
return std::make_pair(x, y);
}
What I am trying to do:
1. scale uniformly an array of points around a point.
2. A point has to be an average point of array of points.
The code below, seems to work, but I do not know if it is the proper way of doing that.
I know that uniform scaling is simply multiplying points by some value, but this is scaling on 0,0,0 point, how to do it around mean point?
The code could be subdivided by following steps:
Get the average point of the array of points, by summing up all positions and dividing by a number of points.
Ratio is scaling value
Then I do vector subtraction to get a vector pointing from point to average point.
I normalize that vector (I get unit vector)
Then I add that normalized vector to current point multiplied by (1 - ratio)*0.5
This last bit 5th point came totally from checking total length of the value.
All examples I came up before was using matrices in math, and I really not capable of reading matrix operations.
Is it the correct uniform scaling method, if it's not could you point out what I am doing wrong?
//Get center of a curve
//That is average of all points
MatMxN curveCenter = MatMxN::Zero(2, 1); //This is just 1 vector/point with x and y coordinates
for (int i = 0; i < n; i++)
curveCenter += points.col(i);
curveCenter /= n;
//Scaling value
float ratio = 1.3;
//Get vector pointing to center and move by ratio
for (int i = 0; i < n; i++) {
MatMxN vector = curveCenter - points.col(i);
MatMxN unit = vector.normalized();
points.col(i) += unit*(1 - ratio)*0.5; //points.col(i) this is point in array
}
In order to scale points using a specific center point (other than 0), follow these steps:
Substract center from point MatMxN vector = points.col(i) - curveCenter;
Multiply vector by scaling factor vector *= ratio
Add center to the scaled vector to get new point points.col(i) = vector + curveCenter
This approach can be resolved to something remotely similar to your formula. Lets call the center C, the point to be scaled P0, the scaled point P1 and the scaling factor s. The above 3 steps can be written as:
v0 = P0 - C
v1 = s * v0
P1 = v1 + C
=>
P1 = s * P0 + C * (1 - s)
Now we define P1 = P0 + x for some x:
P0 + x = s * P0 + C * (1 - s)
=>
x = s * P0 + C * (1 - s) - P0
= C * (1 - s) - P0 * (1 - s)
= (C - P0) * (1 - s)
So the update could be written as follows instead of using the 3 steps mentioned:
MatMxN vector = curveCenter - points.col(i);
points.col(i) += vector * (1 - ratio);
However, I prefer to write the substractions in reverse, because it is closer to the original steps and easier to understand by intuition:
MatMxN vector = points.col(i) - curveCenter;
points.col(i) += vector * (ratio - 1);
I don't know where you found the normalize and *0.5 ideas.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
How to calculate endpoints of the shortest line connecting two circles without using the trig functions?
Two circles and a line
The principle explained below is quite intuitive - instead of analyzing two-dimensional task we divide it in two one-dimensional operations. To be precise we take apart x and y coordinate values for known circle centers and calculate values separately. We calculate new x' and y' only knowing the distance between circle centers and the proportions of radii of said circles to the distance between centers.
(x1 , y1 ), (x2 , y2 ), r1, r2 - known values
(x1', y1'), (x2', y2') - values we are looking for
And all you need to calculate the values we are looking for are following operations:
ΔY = y2 - y1
ΔX = x2 - x1
L = √(ΔX² + ΔY²)
r1L = r1 / L
r2L = r2 / L
y1' = y1 + ΔY * r1L
y2' = y2 - ΔY * r2L
x1' = x1 + ΔX * r1L
x2' = x2 - ΔX * r2L
And you get (x1', y1') and (x2', y2')
The theory behind this calculation is as follows...
Having two circles with their radii r1 and r2 and center coordinates (x1, y1) and (x2, y2) we need to find points (x1', y1') and (x2', y2') at which the line connecting two centers intersects the circles.
Having centers of the two circles (x1,y1) and (x2,y2) we calculate ΔX and ΔY which will be used later twice.
ΔY = y2 - y1 It is worth noting here that Δ can
ΔX = x2 - x1 be negative if x1 > x2 or y1 > y2
First to calculate distance between the centers using Pythagoras theorem:
L = √(ΔX² + ΔY²)
And second time to calculate the offsets using the ratios of the radii to the L (the length of the whole line).
Now looking at the plot below we see that we have a trapezoid with one of the sides being the y axis and the other the line connecting circles' centers.
We know that first circle radius is r1 and the length between centers is L.
We also know that line paralel to the base line splitting trapezoid splits its sides with the same ratios.
Because we know the distance L and the radius r1 we can calculate the ratio.
r1L = r1 / L
Now we can use this ratio to get the point (0, y2').
y1' = y1 + ΔY * r1L
So now we have got the y component of (x1', y1') coordinate. We do similarly with y2'.
r2L = r2 / L
y2' = y2 - ΔY * r2L
To get x1' and x2' we use the x axis to form the other trapezoid and similarly repeat steps shown above.
x1' = x1 + ΔX * r1L
x2' = x2 - ΔX * r2L
As a result we end up with new endpoints (x1', y1') and (x2', y2').
It has to be noted that x1' and y1' values are calculated by adding to them but x2' and y2' values are calculated by subtracting from them. It is so because we initially assume that (x1, y1) is closer to the center coordinate (0, 0), i.e. x1 < x2 and y1 < y2, in ΔY = y2 - y1 and ΔX = x2 - x1.
Imagine a line between the center of the two circles. Find the points where that line intersects the circles. Your line is between those two points.
Call the centers of the two circles (x1,y1) and (x2,y2).
ΔY = y2-y1 \___ for the whole line (blue-red-blue)
ΔX = x2-x1 /
The length of the line between the circle centers is:
L = √(ΔX² + ΔY²)
Using the each circle's radius, r, you can compute the Δy and Δx from the center to the other end of the blue line:
Δx = r/L ΔX
Δy = r/L ΔY
So the points are (x1+Δx, y1+Δy) and similarly for the other blue line.
Now you have the two endpoints of the red line.
Now, on each end you need a line (the blue part) whose length is equal to the radius of the relevant circle. At this point you can forget about the circles!
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
Does anyone know a very simple physics engine, or just a set of basic functions that could complete these tasks: Simple point, line, and rectangle collision detection? I looked at Box2D but it is way too advanced for what I am making. I just need some simple code. Thanks in advance!
Here's my shot at point/line collision detection. The important thing is to avoid trig functions, divisions, and other expensive operations so as not to slow things down too much.
As GMan's comment notes, you need to bear in mind that the point will be moving. So you'll have the current position of the point (let's call it A) and the possible new position of the point (B). You need to find out if, when the point moves from A to B, it would collide with a line.
Let's call the start and end points of the line C and D. A collision will occur only if the lines AB and CD intersect.
Let's describe the line AB using the standard equation Ux + Vy + W = 0. After some algebra, the equation comes out as:
(ay - by) x + (bx - ax) y + ax by - bx ay = 0
We can describe the line CD in terms of a parameter t and constants X Y U V:
x = X + Ut
y = Y + Vt
It's helpful if we set t=0 at point C, and t=1 at point D. By considering t=0 we can work out X and Y. And by considering t=1 we can work out U and V. This gives
x = cx + (dx - cx) t
y = cy + (dy - cy) t
To find the intersection point of the two lines, substitute these into the equation we found for AB, which gives
(ay - by) (cx + (dx - cx) t) + (bx - ax) (cy + (dy - cy) t) + ax by - bx ay = 0
This reduces to
t = (ax by - bx ay + bx cy - cx by + cx ay - ax cy) / q
where q = (ay - by)(cx - dx) - (ax - bx)(cy - dy)
If q is zero, the lines are parallel and do not meet.
If 0 < t < 1 then the line extrapolated from AB intersects CD.
But we still don't know that this intersection is actually between the points A and B. So we need to repeat all the previous steps, swapping AB and CD, and writing the line AB in terms of a parameter s. This gives:
s = (cx dy - dx cy + dx ay - ax dy + ax cy - cx ay) / q
If 0 < s < 1 then the line extrapolated from CD intersects AB.
That's it. So in your code you start by calculating q. If q is zero then the lines are parallel. Otherwise, go on to calculate t and s. If 0 < t < 1 and 0 < s < 1 then a collision is about to happen. To find the location of the collision, substitute t or s back into the original equations for CD.
For extra speed you can remove the divisions by q - it's possible to just check whether the top half of each fraction is in the correct range, and then each check should only need 10 multiplication operations.
Is there a reason you couldn't use basic geometry for this?
Two points collide when their coordinates are the same.
A point intersects with a line when its position is a solution to the equation for the line.
A point intersects a rectangle when the point is bounded by the rectangle.
More complex composite cases can be constructed by composing these cases. Were you specifically looking for a library for some reason?
I'm creating a 2D game and want to test for collision between an OBB (Oriented Bounding Box) and a Circle. I'm unsure of the maths and code to do this. I'm creating the game in c++ and opengl.
Since both your shapes are convex, you can use the Separating Axis Theorem. Here's a tutorial on how to implement an algorithm to do this.
Essentially, you try to find if it's possible to put a line somewhere that's between the two shapes and if you can't find one, then you know they're colliding.
References and general answer taken from this question.
Here's what I would do, in pseudocode:
function does_line_go_through_circle (original_line, circle_centerpoint, radius):
original_slope = get_slope_of_line (original_line)
perpendicular_slope = 1/original_slope
perpendicular_line = create_line_with_slope_through_point (perpendicular_slope, circle_centerpoint)
intersect_point = intersection_of_infinite_lines (perpendicular_line, original_line)
if point_is_on_line (intersect_point, original_line):
finite_line_along_radius = create_finite_line_between_points (circle_centerpoint, intersect_point)
if length_of_line (finite_line_along_radius) < length_of_line (radius):
return true
end
end
return false
end
function does_box_intersect_with_circle (bounding_box, circle):
for each side in bounding_box:
if does_line_go_through_circle (side, circle.center, circle.radius):
return true
end
end
return false
end
Keep in mind, I'm a little rusty on this stuff, I might be wrong.
Anyway, it should be trivial to implement this in C++.
We will divide the rectangle into 4 finite lines.
We can construct the line equation ax + by + c = 0 connecting the points (x1, y1) and (x2, y2) as follows:
mx - y + c = 0
where m = (y2-y1)/(x2-x1)
Shortest (perpendicular) distance from a line ax + by + c = 0 to a point (xc, yc) is given by the expression:
d = (a*xc + b*yc + c) / sqrt(a*a + b*b)
or d = (m*xc - yc + c) / sqrt(m*m + 1) according the the above equation
For infinite lines, you can check if 'd' is less than the radius of the circle.
But for finite lines, you'd also have to make sure whether the point of contact is within the line.
Now m = tan(angle). You can have
cos = 1 / sqrt(m*m + 1); sin = m / sqrt(m*m + 1)
Then you can calculate the point of contact as
xp = xc + d*cos; yp = yc + d*sin
And to check whether (xp, yp) lies in between the points connecting line, you can do a simple check as
if(x1 < xp < x2 && y1 < yp < y2)
return true
depending upon which is greater among x1 x2 and y1 y2.
You can repeat the same algorithm for all the four lines of a rectangle by passing the points.
Please correct me if I'm wrong somewhere.