Direct way of computing clockwise angle between 2 vectors - c++

I want to find out the clockwise angle between 2 vectors(2D, 3D).
The clasic way with the dot product gives me the inner angle(0-180 degrees) and I need to use some if statements to determine if the result is the angle I need or its complement.
Do you know a direct way of computing clockwise angle?

2D case
Just like the dot product is proportional to the cosine of the angle, the determinant is proprortional to its sine. So you can compute the angle like this:
dot = x1*x2 + y1*y2 # dot product between [x1, y1] and [x2, y2]
det = x1*y2 - y1*x2 # determinant
angle = atan2(det, dot) # atan2(y, x) or atan2(sin, cos)
The orientation of this angle matches that of the coordinate system. In a left-handed coordinate system, i.e. x pointing right and y down as is common for computer graphics, this will mean you get a positive sign for clockwise angles. If the orientation of the coordinate system is mathematical with y up, you get counter-clockwise angles as is the convention in mathematics. Changing the order of the inputs will change the sign, so if you are unhappy with the signs just swap the inputs.
3D case
In 3D, two arbitrarily placed vectors define their own axis of rotation, perpendicular to both. That axis of rotation does not come with a fixed orientation, which means that you cannot uniquely fix the direction of the angle of rotation either. One common convention is to let angles be always positive, and to orient the axis in such a way that it fits a positive angle. In this case, the dot product of the normalized vectors is enough to compute angles.
dot = x1*x2 + y1*y2 + z1*z2 #between [x1, y1, z1] and [x2, y2, z2]
lenSq1 = x1*x1 + y1*y1 + z1*z1
lenSq2 = x2*x2 + y2*y2 + z2*z2
angle = acos(dot/sqrt(lenSq1 * lenSq2))
Edit: Note that some comments and alternate answers advise against the use of acos for numeric reasons, in particular if the angles to be measured are small.
Plane embedded in 3D
One special case is the case where your vectors are not placed arbitrarily, but lie within a plane with a known normal vector n. Then the axis of rotation will be in direction n as well, and the orientation of n will fix an orientation for that axis. In this case, you can adapt the 2D computation above, including n into the determinant to make its size 3×3.
dot = x1*x2 + y1*y2 + z1*z2
det = x1*y2*zn + x2*yn*z1 + xn*y1*z2 - z1*y2*xn - z2*yn*x1 - zn*y1*x2
angle = atan2(det, dot)
One condition for this to work is that the normal vector n has unit length. If not, you'll have to normalize it.
As triple product
This determinant could also be expressed as the triple product, as #Excrubulent pointed out in a suggested edit.
det = n · (v1 × v2)
This might be easier to implement in some APIs, and gives a different perspective on what's going on here: The cross product is proportional to the sine of the angle, and will lie perpendicular to the plane, hence be a multiple of n. The dot product will therefore basically measure the length of that vector, but with the correct sign attached to it.

To compute angle you just need to call atan2(v1.s_cross(v2), v1.dot(v2)) for 2D case.
Where s_cross is scalar analogue of cross production (signed area of parallelogram).
For 2D case that would be wedge production.
For 3D case you need to define clockwise rotation because from one side of plane clockwise is one direction, from other side of plane is another direction =)
Edit: this is counter clockwise angle, clockwise angle is just opposite

This answer is the same as MvG's, but explains it differently (it's the result of my efforts in trying to understand why MvG's solution works). I'm posting it on the off chance that others find it helpful.
The anti-clockwise angle theta from x to y, with respect to the viewpoint of their given normal n (||n|| = 1), is given by
atan2( dot(n, cross(x,y)), dot(x,y) )
(1) = atan2( ||x|| ||y|| sin(theta),  ||x|| ||y|| cos(theta) )
(2) = atan2( sin(theta), cos(theta) )
(3) = anti-clockwise angle between x axis and the vector (cos(theta), sin(theta))
(4) = theta
where ||x|| denotes the magnitude of x.
Step (1) follows by noting that
cross(x,y) = ||x|| ||y|| sin(theta) n,
and so
dot(n, cross(x,y))
= dot(n, ||x|| ||y|| sin(theta) n)
= ||x|| ||y|| sin(theta) dot(n, n)
which equals
||x|| ||y|| sin(theta)
if ||n|| = 1.
Step (2) follows from the definition of atan2, noting that atan2(cy, cx) = atan2(y,x), where c is a scalar. Step (3) follows from the definition of atan2. Step (4) follows from the geometric definitions of cos and sin.

Since one of the simplest and most elegant solutions is hidden in one the comments, I think it might be useful to post it as a separate answer.
acos can cause inaccuracies for very small angles, so atan2 is usually preferred. For the 3D case:
dot = x1 * x2 + y1 * y2 + z1 * z2
cross_x = (y1 * z2 – z1 * y2)
cross_y = (z1 * x2 – x1 * z2)
cross_z = (x1 * y2 – y1 * x2)
det = sqrt(cross_x * cross_x + cross_y * cross_y + cross_z * cross_z)
angle = atan2(det, dot)

Scalar (dot) product of two vectors lets you get the cosinus of the angle between them.
To get the 'direction' of the angle, you should also calculate the cross product, it will let you check (via z coordinate) is angle is clockwise or not (i.e. should you extract it from 360 degrees or not).

For a 2D method, you could use the law of
cosines and the "direction" method.
To calculate the angle of segment P3:P1
sweeping clockwise to segment P3:P2.
P1 P2
P3
double d = direction(x3, y3, x2, y2, x1, y1);
// c
int d1d3 = distanceSqEucl(x1, y1, x3, y3);
// b
int d2d3 = distanceSqEucl(x2, y2, x3, y3);
// a
int d1d2 = distanceSqEucl(x1, y1, x2, y2);
//cosine A = (b^2 + c^2 - a^2)/2bc
double cosA = (d1d3 + d2d3 - d1d2)
/ (2 * Math.sqrt(d1d3 * d2d3));
double angleA = Math.acos(cosA);
if (d > 0) {
angleA = 2.*Math.PI - angleA;
}
This has the same number of transcendental
operations as suggestions above and only one
more or so floating point operation.
the methods it uses are:
public int distanceSqEucl(int x1, int y1,
int x2, int y2) {
int diffX = x1 - x2;
int diffY = y1 - y2;
return (diffX * diffX + diffY * diffY);
}
public int direction(int x1, int y1, int x2, int y2,
int x3, int y3) {
int d = ((x2 - x1)*(y3 - y1)) - ((y2 - y1)*(x3 - x1));
return d;
}

If by "direct way" you mean avoiding the if statement, then I don't think there is a really general solution.
However, if your specific problem would allow loosing some precision in angle discretization and you are ok with loosing some time in type conversions, you can map the [-pi,pi) allowed range of phi angle onto the allowed range of some signed integer type. Then you would get the complementarity for free. However, I didn't really use this trick in practice. Most likely, the expense of float-to-integer and integer-to-float conversions would outweigh any benefit of the directness. It's better to set your priorities on writing autovectorizable or parallelizable code when this angle computation is done a lot.
Also, if your problem details are such that there is a definite more likely outcome for the angle direction, then you can use compilers' builtin functions to supply this information to the compiler, so it can optimize the branching more efficiently. E.g., in case of gcc, that's __builtin_expect function. It's somewhat more handy to use when you wrap it into such likely and unlikely macros (like in linux kernel):
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)

For 2D case atan2 can easily calculate angle between (1, 0) vector (X-axis) and one of your vectors.
Formula is:
Atan2(y, x)
So you can easily calculate difference of two angles relatively X-axis
angle = -(atan2(y2, x2) - atan2(y1, x1))
Why is it not used as default solution? atan2 is not efficient enough. Solution from the top answer is better. Tests on C# showed that this method has 19.6% less performance (100 000 000 iterations). It's not critical but unpleasant.
So, another info that can be useful:
The smallest angle between outer and inner in degrees:
abs(angle * 180 / PI)
Full angle in degrees:
angle = angle * 180 / PI
angle = angle > 0 ? angle : 360 - angle
or
angle = angle * 180 / PI
if (angle < 0) angle = 360 - angle;

A formula for clockwise angle,2D case, between 2 vectors, xa,ya and xb,yb.
Angle(vec.a-vec,b)=
pi()/2*((1+sign(ya))*
(1-sign(xa^2))-(1+sign(yb))*
(1-sign(xb^2))) +pi()/4*
((2+sign(ya))*sign(xa)-(2+sign(yb))*
sign(xb)) +sign(xa*ya)*
atan((abs(ya)-abs(xa))/(abs(ya)+abs(xa)))-sign(xb*yb)*
atan((abs(yb)-abs(xb))/(abs(yb)+abs(xb)))

just copy & paste this.
angle = (acos((v1.x * v2.x + v1.y * v2.y)/((sqrt(v1.x*v1.x + v1.y*v1.y) * sqrt(v2.x*v2.x + v2.y*v2.y))))/pi*180);
you're welcome ;-)

Related

Determine Next Point on a Line Between Point A and B From A

I have a 2D Coordinate system where The Origin Starts at the top Left
(Y Is higher as I move downward)
I am Given Two Points in Space, Lets Say Point A, and Point B.
How can I determine that next Point on the line From Point A to Point B?
For example, I have Point A(10, 10) and Point B (1,1)
I know the point I'm looking for is (9,9).
But how do I do this mathematically?
For say a more complicated Set of points
A(731, 911) and B(200, 1298)
I'm trying to move my mouse, one pixel at a time from its current location to a new one.
This doesn't work, but honestly I'm stumped where to begin.
int rise = x2 - 460; //(460 is Point A x)
int run = y2 - 360;//(360 is Point A Y)
float slope = rise / run;
int newx = x1 + ((slope / slope) * 1); //x1 Is my current mouse POS x
int newy = y1 + (slope * -1);//y1 is my current mouse Pos y
It almost works but seems inverted, and wrong.
You already have the slope, so to get the next point on the line (there are infinitely many), you have to choose a step value or just arbitrarily pick one of the points.
Given A(y1, x1), your goal in finding a new point, B(y2, x2) is that it must satisfy the equation: (y2 - y1) / (x2 - x1) = slope.
To simplify, (x2 - x1) * slope = y2 - y1
You already have x1, slope, y1, and you can choose any arbitrary x2, so when you plug all those into the equation, you can simplify it further to:
y2 = (x2 - x1) * slope + y1
To illustrate this with your other points (A(731, 911) and C(200, 1298)) and say you want to find a new point B, we can proceed as follows:
Find the slope first:
float slope = (1298 - 911) / (200 - 731); // -0.728813559322
Choose x and solve for y:
x1 = 731, slope = -0.728813559322, y1 = 911
Choose x2 = 500 and solving for y2, we get:
float y2 = (500 - 731) * -0.728813559322 + 911; // 1079.355932203382
So your new point is:
B(500, 1079.355932203382)
You can verify this new point still has the same slope to point C
With A = (x1,y1) and B = (x2,y2) the line is (expressed in two same equations):
(1) y = (x-x1)*(y2-y1)/(x2-x1) + y1
(2) x = (y-y1)*(x2-x1)/(y2-y1) + x1
To find next point, put x1+1 (or x1-1 you know) in equation (1) and find y and also put y1+1 or y1-1 in equation (2) and find x.
You can decide which one is better choice. Take care of vertical or horizontal lines, where one of the equations won't work.
NOTE: do not cast floating point result to int. Do round instead.

Polygon clipping - a little elaboration?

I have been reading a lot about the sutherland hodgman polygon clipping algorithm and understand the general idea. However, when I see the actual implementation of it (like the one below), I get confused about the coordinate comparisons such as those in the intersection and inside methods. Therefore, I was wondering if someone could elaborate on what and why? I see a ton of videos and articles explaining the general concepts but I really have trouble finding some explanation of the actual details regarding the implementation.
bool inside(b2Vec2 cp1, b2Vec2 cp2, b2Vec2 p) {
return (cp2.x-cp1.x)*(p.y-cp1.y) > (cp2.y-cp1.y)*(p.x-cp1.x);
}
b2Vec2 intersection(b2Vec2 cp1, b2Vec2 cp2, b2Vec2 s, b2Vec2 e) {
b2Vec2 dc( cp1.x - cp2.x, cp1.y - cp2.y );
b2Vec2 dp( s.x - e.x, s.y - e.y );
float n1 = cp1.x * cp2.y - cp1.y * cp2.x;
float n2 = s.x * e.y - s.y * e.x;
float n3 = 1.0 / (dc.x * dp.y - dc.y * dp.x);
return b2Vec2( (n1*dp.x - n2*dc.x) * n3, (n1*dp.y - n2*dc.y) * n3);
}
//http://rosettacode.org/wiki/Sutherland-Hodgman_polygon_clipping#JavaScript
//Note that this only works when fB is a convex polygon, but we know all
//fixtures in Box2D are convex, so that will not be a problem
bool findIntersectionOfFixtures(b2Fixture* fA, b2Fixture* fB, vector<b2Vec2>& outputVertices)
{
//currently this only handles polygon vs polygon
if ( fA->GetShape()->GetType() != b2Shape::e_polygon ||
fB->GetShape()->GetType() != b2Shape::e_polygon )
return false;
b2PolygonShape* polyA = (b2PolygonShape*)fA->GetShape();
b2PolygonShape* polyB = (b2PolygonShape*)fB->GetShape();
//fill subject polygon from fixtureA polygon
for (int i = 0; i < polyA->GetVertexCount(); i++)
outputVertices.push_back( fA->GetBody()->GetWorldPoint( polyA->GetVertex(i) ) );
//fill clip polygon from fixtureB polygon
vector<b2Vec2> clipPolygon;
for (int i = 0; i < polyB->GetVertexCount(); i++)
clipPolygon.push_back( fB->GetBody()->GetWorldPoint( polyB->GetVertex(i) ) );
b2Vec2 cp1 = clipPolygon[clipPolygon.size()-1];
for (int j = 0; j < clipPolygon.size(); j++) {
b2Vec2 cp2 = clipPolygon[j];
if ( outputVertices.empty() )
return false;
vector<b2Vec2> inputList = outputVertices;
outputVertices.clear();
b2Vec2 s = inputList[inputList.size() - 1]; //last on the input list
for (int i = 0; i < inputList.size(); i++) {
b2Vec2 e = inputList[i];
if (inside(cp1, cp2, e)) {
if (!inside(cp1, cp2, s)) {
outputVertices.push_back( intersection(cp1, cp2, s, e) );
}
outputVertices.push_back(e);
}
else if (inside(cp1, cp2, s)) {
outputVertices.push_back( intersection(cp1, cp2, s, e) );
}
s = e;
}
cp1 = cp2;
}
return !outputVertices.empty();
}
(code stolen from iforce2d :) )
You say you understand the general idea, presumably from reading something like Sutherland Hodgman Algorithm. That explains at a high level exactly what inside and intersection do.
As to the details of how they achieve their objectives, that is all just straight up text book linear algebra.
inside is testing the sign of (cp2 - cp2) cross (p - cp1) and returning true iff the sign is strictly greater than zero. You could rewrite the return statement as:
return (cp2.x-cp1.x)*(p.y-cp1.y) - (cp2.y-cp1.y)*(p.x-cp1.x) > 0;
by moving the second term to the left of the > which gives you exactly the cross product on the left.
Note that a cross product is typically a vec3 cross vec3 operation and requires computation of all three terms. However, we're doing this in 2d meaning the vec3s have the form (x, y, 0). Therefore we only need to compute the z output term, since the cross must be perpendicular to the xy plane, and therefore be of the form (0, 0, value).
intersection finds the point at which two vectors intersect using exactly the algorithm listed here: Line Intersection from Two Points. In particular, we care about the formula immediately following the text "The determinants can be written out as:"
In the context of that formula n1 is (x1 y2 - y1 x2), n2 is (x3 y4 - y3 x4) and n3 is 1 / ((x1 - x2) (y3 - y4) - (y1 - y2) (x3 - x4))
-- EDIT --
To cover the issue raised in the comments, here is as full an explanation as I can give for why the return value from inside() is a test of the sign of the cross product.
I'm going to go off on a slight tangent, show my age, and note that the cross product formula has a very simple memory aid. You just need to remember the first magic word from Woods and Crowther's text adventure game Colossal Cave. xyzzy.
If you have two vectors in three dimensions: (x1, y1, z1) and (x2, y2, z2), their cross product (xc, yc, zc) is evaluated thus:
xc = y1 * z2 - z1 * y2;
yc = z1 * x2 - x1 * z2;
zc = x1 * y2 - y1 * x2;
Now, look at the first line, remove the c, 1 and 2 suffixes from the terms, all the spaces and operators and just look at the remaining letters. It's the magic word. Then you just go vertically down, replacing x with y, y with z and z with x as you go from line to line.
Getting back to business, both the terms on the right of the expansions of xc and yc contain either z1 or z2. But we know that both of these are zero since our input vectors are in the xy plane, and therefore have a zero z component. That's why we can completely elide computing those two terms, because we know they'll be zero.
This is 100% consistent with the definition of what the cross product does, the resulting vector is always perpendicular to both input vectors. Hence if both input vectors are in the xy plane, we know the output vector must be perpendicular to the xy plane, and therefore have the form (0, 0, z)
So, what do we have for the z term?
zc = x1 * y2 - y1 * x2;
in this case vector 1 is cp2-cp1 and vector 2 is p-cp1. So plugging that into the above we get:
zc = (cp2.x-cp1.x)*(p.y-cp1.y) - (cp2.y-cp1.y)*(p.x-cp1.x);
But as noted, we don't care about its value, only it's sign. We want to know if that is greater than zero. Hence:
return (cp2.x-cp1.x)*(p.y-cp1.y) - (cp2.y-cp1.y)*(p.x-cp1.x) > 0;
which is then rewritten as:
return (cp2.x-cp1.x)*(p.y-cp1.y) > (cp2.y-cp1.y)*(p.x-cp1.x);
Finally, what does the sign of that term have to do with whether the point p is inside or outside the clipping polygon? You are quite correct that all the clipping takes place in the 2d xy plane, so why are we involving 3d operations at all?
The important thing to realize is that the cross product formula in 3d is not commutative. The order of the two vector operands is significant, in terms of the angle between them. The first image on the Wikipedia page for Cross Product shows it perfectly. In that diagram, if you look down from above, when evaluating a cross b, the shortest angular direction from a to b is counter-clockwise. In that instance, that leads to a cross product with a positive z value, assuming positive z goes up the page. However if you evaluate b cross a, the shotest angular distance from b to a is clockwise, and the cross product has a negative z value.
Thinking back to the Wikipedia page for the algorithm itself, you've got the blue "clipping" line that works its way counter-clockwise around the clipping polygon. If you think of that vector as always having positive magnitude in the counter-clockwise direction it'll always be cp2 - cp1 for any pair of adjacent vertices in the clipping polygon.
Keeping this in mind, imagine what you'd see if you stood at cp1, with your nose pointed straight at cp2. The interior of the clipping polygon will be on your left, and the exterior on the right. Now consider two points p1 and p2. We'll say p1 is inside the clipping poly, and p2 is outside. That means that the quickest way to point yourt nose at p1 is to rotate counter-clockwise, and the quickest way to point at p2 is to rotate clockwise.
So by studying the sign of the cross product, we're really asking 'Do we rotate clockwise or counter-clockwise from the current edge to look at the point' which equates to asking if the point is inside the clipping polygon or outside.
I'll add one final suggestion. If you're at all interested in this sort of thing, or 3d rendering, or any programming that involves modelling the mathematical representation of the real world, taking a good solid course in linear algebra that covers the likes of cross products, dot products, vectors, matrices and the interactions between them all will be one of the best things you can ever do. It will provide a very strong foundation for a fair amount of what is done with computers.

Speed of quadratic curve

I'm writing a 2d game and I have birds in a camera-space. I want to make them fly. So, I generate 3 ~random points. First one is left-upper side, second: middle-bottom, third: right-upper.
As a result I have 180deg rotated triangle.
To move a bird through the curve's path I have a t-parameter which is increased in each frame (render loop) by some delta.
The problem is that in different curves birds have different speed. If the triangle is "wide" (1) they are more slowly, if it's stretched by Y-coordinate (2), the speed is very fast.
But I want to make speed equal at different curves. It's logically, that I have to change delta which is appended each frame for each curve.
I've tried to solve it like this:
Find the ~length of the curve by summing length of 2 vectors: P1P2 and P2P3.
Than I've defined the speed for 1 virtual meter per frame. A little pseudocode:
float pixelsInMeter = 92.f; // One virtual meter equals to this number of pixels
float length = len(P1P2) + len(P2P3)
float speed = 0.0003f; // m/frame
// (length * speed) / etalon_length
float speedForTheCurve = toPixels( (toMeters(length) * speed) / 1.f);
// ...
// Each frame code:
t += speedForTheCurve;
Vector2 newPos = BezierQuadratic(t, P1, P2, P3);
But birds anyway have different speed. What's wrong? Or maybe there is a better way.
The Bezier function you're using is a parametrized function with bounds [0...1]. You're mucking with the step-size, which is why you're getting crazy speeds. Generally speaking, the distance d is the dependent variable in the equation, which says to me that their speeds will be different based on the length of the curve.
Since speed is your dependent variable, we're going to vectorize your function by computing the step-size.
Check out this pseudocode:
P1 = (x1, y1)
P2 = (x2, y2)
P3 = (x3, y3)
int vec[100][2]
int getPoint(int p1, int p2, float stepSize) {
return p1 + (p2 - p1)*stepSize;
}
for (float i = 0.0; i < 1.0; i += 0.01 ) {
int newX = getPoint(getPoint(x1, x2, i), getPoint(x2, x3, i), i);
int newY = getPoint(getPoint(y1, y2, i), getPoint(y2, y3, i), i);
vec[iter++][0] = newX;
vec[iter][1] = newY;
}
You can get the delta values by performing a first difference but I don't think that's necessary. As long as you move all the birds the appropriate distance based on the step iteration they will all move different distances but they will start and end their trajectories identically.
From your equation, we can compute the pixel delta step size:
int pixelsToMove = toMeter(sqrt((x2 - x1)^2 + (y2 - y1)^2))/pixelsInMeter;
Which will give you the appropriate amount of pixels to move the bird. That way they'll all move different step sizes, but their speeds will be different. Does that make sense?
Or, try something like this (much harder):
Obtain the actual quadratic function of the three points you chose.
Integrate the quadratic between two xy rectangular coordinate
Convert computed length into pixels or whatever you're using
Obtain dependent variable speed so all curves finish at the same time.
Let's start with quadratic stuff:
y = Ax^2 + Bx + C where A != 0, so since you have three points, you will need three equations. Using algebra, you can solve for the contants:
A = (y3 - y2)/((x3 - x2)(x3 - x1)) - (y1 - y2)/((x1 - x2)(x3 - x1))
B = (y1 - y2 + A(x2^2 - x1^2))/(x1 - x2)
C = y1 - Ax1^2 - Bx1
Then you can use the formula above to obtain a closed-form arc length. Check this website out, wolfram will integrate it for you and you just have to type it:
Closed form solution for quadradic integration
Now that you've computed the arc length, convert actualArcLength to the speed or whatever unit you're using:
float speedForTheCurve = toPixels( (toMeters(actualArcLength) * speed) / 1.f);

Find 3rd point in a line using c++

I am working in c++ application. And its new to me. Here I write a function which gain two coordinates of a line. I have to process these coordinates and find another point which in that same line.
I will gain A(x1,y1) and B(x2,y2) coordinates.
need to find
C(x3,y3) coordinates.
Therefore I calculate the Slope of given line.
Double slope = (x1-x2)/(y1-y2);
And I know the distance of 3rd point from A point.
Double dis = sqrt(pow(x2-x1) + pow(y2-y1)) * 1.35 ;
I want to find new coordinates x3 ,y3 using Slope and dis.
Can anyone help me to solve this please.
To calculate the x3 I can use mathematical part,
x3 = slope * y3 -------------------1
dis = sqrt(pow(x3-x1) + pow(y3-y1)) ------------2
using these 2 equations which generating in run time , I want to calculate x3 and y3.
Too much math.
x3 = (x1 - x2) * 1.35 + x2
y3 = (y1 - y2) * 1.35 + y2
Unless you are working with a "1.5d" graph y=y(x) you should never use formulas based on y=m*x+q because that doesn't work for vertical lines (and works poorly for near-vertical lines).
In your case the best approach is to use the parametric equation for a line
x = x1 + t * dx
y = y1 + t * dy
where dx = x2 - x1 and dy = y2 - y1 are proportional to the components of the direction unit vector oriented from P1 to P2 and are used instead of m and q to define the line (avoiding any problem with vertical or almost vertical lines).
If you need a point on a specific distance then you just need to find the actual unit vector components with
double dx = x2 - x1;
double dy = y2 - y1;
double dist = sqrt(dx*dx + dy*dy);
dx /= dist;
dy /= dist;
and then the coordinates of the point you need are
double x3 = x1 + prescribed_distance * dx;
double y3 = y1 + prescribed_distance * dy;
or using -prescribed_distance instead depending on which side you want the point: toward P2 or away from it?
If however the prescribed distance is proportional to the current distance between the two points the normalization is not needed and the result can be the simpler:
double x3 = x1 + (x2 - x1) * k;
double y3 = y1 + (y2 - y1) * k;
where k is the ratio between the prescribed distance and the distance between the two points (once again with positive or negative sign depending on which side you are interested in).
By using parametric equations x=x(t), y=y(t) instead of explicit equations y=y(x) in addition to not having artificial singularity problems that depend on the coordinate system you also get formulas that are trivial to extend in higher dimensions. For example for a 3d line you just basically need to add z coordinate to the above formulas in the very same way x and y are used...
If you substitute the first equation "y3 = slope * x3" into the 2nd equation "dis = sqrt(pow(x3-x1) + pow(y3-y1))", and square both sides, you get a quadratic which you can solve using the quadratic formula.
After substitution you get:
dis^2 = (x3-x1)^2 + (slope*x3 - y1)^2
Square both sides:
(slope^2+1)*x3^2 + (-2*slope*y1-2*x1) + 2*y1^2 = dis^2
Solve for x3 using the quadratic formula:
x3 = (2*slope*y1+2*x1) +/- sqrt((2*slope*y1+2*x1)^b - 4*(slope^2+1)*(2*y1^2-dis^2))/(2*(slope^2+1))
Substitute x3 into the first equation to get y3:
y3 = slope * x3

(C++) Need to figure out all points within a radius using reg. 2D windows coord. system

Sorry in advance, I'm struggling a bit with how to explain this... :)
Essentially, I've got a typical windows coordinate system (the Top, Left is 0,0). If anybody's familiar with the haversine query, like in SQL, it can get all points in a radius based on latitude and longitude coordinates.
I need something much simpler, but my math skills ain't all up to par! Basically, I've got random points scattered throughout about a 600x400 space. I have a need to, for any X,Y point on the map, run a query to determine how many other points are within a given radius of that one.
If that's not descriptive enough, just let me know!
Straightforward approach:
You can calculate the distance between to points using the Pythagorean theorem:
deltaX = x1 - x2
deltaY = y1 - y2
distance = square root of (deltaX * deltaX + deltaY * deltaY)
Given point x1,y1, do this for every other point (x2,y2) to see if the calculated distance is within (less than or equal to) your radius.
If you want to make it speedier, calculate and store the square of the radius and just compare against (deltaX * deltaX + deltaY * deltaY), avoiding the square root.
Before doing the Pythagoras, you could also quickly eliminate any point that falls outside of the square that can fully contain the target circle.
// Is (x1, y1) in the circle defined by center (x,y) and radius r
bool IsPointInCircle(x1, y1, x, y, r)
{
if (x1 < x-r || x1 > x+r)
return false;
if (y1 < y-r || y1 > y+r)
return false;
return (x1-x)*(x1-x) + (y1-y)*(y1-y) <= r*r
}
Use Pythagoras:
distance = sqrt(xDifference^2 + yDifference^2)
Note that '^' in this example means "to the power of" and not C's bitwise XOR operator. In other words the idea is to square both differences.
If you only care about relative distance you shouldn't use square root you can do something like:
rSquared = radius * radius #square the radius
foreach x, y in Points do
dX = (x - centerX) * (x - centerX) #delta X
dY = (y - centerY) * (y - centerY) #delta Y
if ( dX + dY <= rSquared ) then
#Point is within Circle
end
end
Using the equation for a circle:
radius ** 2 = (x - centerX) ** 2 + (y - centerY) ** 2
We want to find if a point (x, y) is inside of the circle. We perform the test using this equation:
radius ** 2 < (x - centerX) ** 2 + (y - centerY) ** 2
// (Or use <= if you want the circumference of the circle to be included as well)
Simply substitute your values into that equation. If it works (the inequality is true), the point is inside of the circle. Otherwise, it isn't.