I'm running into a problem where my square of X is always becoming infinite leading to the resulting distance also being infinite, however I can't see anything wrong with my own maths:
// Claculate distance
xSqr = (x1 - x2) * (x1 - x2);
ySqr = (y1 - y2) * (y1 - y2);
zSqr = (z1 - z2) * (z1 - z2);
double mySqr = xSqr + ySqr + zSqr;
double myDistance = sqrt(mySqr);
When I run my program I get user input for each of the co-ordinates and then display the distance after I have run the calulation.
If your inputs are single-precision float, then you should be fine if you force double-precision arithmetic:
xSqr = double(x1 - x2) * (x1 - x2);
// ^^^^^^
If the inputs are already double-precision, and you don't have a larger floating-point type available, then you'll need to rearrange the Euclidean distance calculation to avoid overflow:
r = sqrt(x^2 + y^2 + z^2)
= abs(x) * sqrt(1 + (y/x)^2 + (z/x)^2)
where x is the largest of the three coordinate distances.
In code, that might look something like:
double d[] = {abs(x1-x2), abs(y1-y2), abs(z1-z2)};
if (d[0] < d[1]) swap(d[0],d[1]);
if (d[0] < d[2]) swap(d[0],d[2]);
double distance = d[0] * sqrt(1.0 + d[1]/d[0] + d[2]/d[0]);
or alternatively, use hypot, which uses similar techniques to avoid overflow:
double distance = hypot(hypot(x1-x2,y1-y2),z1-z2);
although this may not be available in pre-2011 C++ libraries.
Try this:
long double myDistance=sqrt(pow(x1-x2,2.0)+pow(y1-y2,2.0)+pow(z1-z2,2.0));
I figured out what was going on, I had copied and pasted the code for setting x1, y1 and z1 and forgot to change it to x2 y2 and z2, It's always the silliest of things with me :P thanks for the help anyway guys
Related
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.
I have the following function in C++ that is supposed to find the area of a triangle using Heron's formula. I haven't made any mistake in the math but it doesn't produce the right result! I am looking at it for more than 3 hours and I can't find any mistake. What am I missing?
float TriangleArea(float x0, float y0, float x1, float y1, float x2, float y2)
{
float area_triangle;
float a, b, c, s;
a=std::sqrt((x0-x1)*(x0-x1)-(y0-y1)*(y0-y1));
b=std::sqrt((x1-x2)*(x1-x2)-(y1-y2)*(y1-y2));
c=std::sqrt((x0-x2)*(x0-x2)-(y0-y2)*(y0-y2));
s=(a+b+c)/2;
area_triangle=std::sqrt((s*(s-a)*(s-b)*(s-c)));
return area_triangle;
}
I haven't made any mistake in the math but it doesn't produce the right result!
If it's not producing the right result, then I think there's a very high chance you made a mistake in the math.
a=std::sqrt((x0-x1)*(x0-x1)-(y0-y1)*(y0-y1));
That - looks suspicious. I'm assuming you're trying to find the distance between (x0, y0) and (x1, y1). If that's the case, you should be adding the two quantities, not subtracting.
I'm not familiar with Heron's formula, but you can use this simpler formula:
area = std::abs(x0 * (y1 - y2) + x1 * (y2 - y0) + x2 * (y0 - y1)) / 2;
Edit: I forgot to mention the abs function for the simplified formula, which was pointed out by Antonio.
I think you have a sign error. The values a, b, and c are the triangle sides, right?
a=std::sqrt((x0-x1)*(x0-x1)+(y0-y1)*(y0-y1));
^
An alternative formula (with demonstration) can be found here
area = fabs((x0 - x2) * (y1 - y0) - (x0 - x1) * (y2 - y0) ) / 2;
(As a side note, if the formula has to be used to test points collinearity, the absolute value can be removed... But then you might need it anyway, as working with floating points you cannot test equality but against some epsilon value)
I am attempting to calculate the point of intersection between lines for a Optical Flow algorithm using a Hough Transform. However, I am not getting the points that I should be when I use my algorithm for calculating the intersections.
I save the Lines as an instance of a class that I created called ImageLine. Here is the code for my intersection method.
Point ImageLine::intersectionWith(ImageLine other)
{
float A2 = other.Y2() - other.Y1();
float B2 = other.X2() - other.X1();
float C2 = A2*other.X1() + B2*other.Y1();
float A1 = y2 - y1;
float B1 = x2 - x1;
float C1 = A1 * x1 + B1 * y1;
float det = A1*B2 - A2*B1;
if (det == 0)
{
return Point(-1,-1);
}
Point d = Point((B2 * C1 - B1 * C2) / det, -(A1 * C2 - A2 * C1) / det);
return d;
}
Is this method correct, or did I do something wrong? As far as I can tell, it should work, as it does for a single point that I hard-coded through, however, I have not been able to get a good intersection when using real data.
Considering the maths side: if we have two line equations:
y = m1 * x + c1
y = m2 * x + c2
The point of intersection: (X , Y), of two lines described by the following equations:
Y = m1 * X + c1
Y = m2 * X + c2
is the point which satisfies both equation, i.e.:
m1 * X + c1 = m2 * X + c2
(Y - c1) / m1 = (Y - c2) / m2
thus the point of intersection coordinates are:
intersectionX = (c2 - c1) / (m1 - m2)
intersectionY = (m1*c1 - c2*m2) / m1-m2 or intersectionY = m1 * intersectionX + c1
Note: c1, m1 and c2, m2 are calculated by getting any 2 points of a line and putting them in the line equations.
(det == 0) is unlikely to be true when you're using floating-point arithmetic, because it isn't precise.
Something like (fabs(det) < epsilon) is commonly used, for some suitable value of epsilon (say, 1e-6).
If that doesn't fix it, show some actual numbers, along with the expected result and the actual result.
For detailed formula, please go to this page.
But I love code so, here, check this code (I get it from github, so all credit goes to the author of that code):
///Calculate intersection of two lines.
///\return true if found, false if not found or error
bool LineLineIntersect(double x1, double y1, //Line 1 start
double x2, double y2, //Line 1 end
double x3, double y3, //Line 2 start
double x4, double y4, //Line 2 end
double &ixOut, double &iyOut) //Output
{
//http://mathworld.wolfram.com/Line-LineIntersection.html
double detL1 = Det(x1, y1, x2, y2);
double detL2 = Det(x3, y3, x4, y4);
double x1mx2 = x1 - x2;
double x3mx4 = x3 - x4;
double y1my2 = y1 - y2;
double y3my4 = y3 - y4;
double xnom = Det(detL1, x1mx2, detL2, x3mx4);
double ynom = Det(detL1, y1my2, detL2, y3my4);
double denom = Det(x1mx2, y1my2, x3mx4, y3my4);
if(denom == 0.0)//Lines don't seem to cross
{
ixOut = NAN;
iyOut = NAN;
return false;
}
ixOut = xnom / denom;
iyOut = ynom / denom;
if(!isfinite(ixOut) || !isfinite(iyOut)) //Probably a numerical issue
return false;
return true; //All OK
}
Assuming your formulas are correct, try declaring all your intermediate arguments as 'double'. Taking the difference of nearly parallel lines could result in your products being very close to each other, so 'float' may not preserve enough precision.
I have two points A (x1,y1) and B (x2,y2) that are given as an input to the program. I have to find a third point C that lies on the line AB and is at a distance 10 away from the point A.
I can easily get the slope of the line but that doesn't give me the full equation for the line. Even if I get the full equation, I am not sure using this equation, how would I find out a point that is x distance away from A.
Any suggestions on how to approach this?
There are always two points on each line:
get the vector from A to B (subtract the coordinates)
normalize the vector (divide by its length; pythagorean theorem)
multiply the vector by 10 or -10
add the vector to A to get C
Note that if A==B, the line is not defined, and this algorithm causes a division by zero. You may want to add a test for equality at the beginning.
You can use the sine or the cosine (times 10) of the angle of the line to get the horizontal or vertical distance of the point that is a distance of 10 from a given point. A shortcut is to use the horizontal or vertical distance divided by the direct distance between the points to get the sine or cosine.
You can do it using vectors like this:
Let D = the difference between B and A (D = B - A)
Then any point on the line can be described by this formula:
point = A + Dt
where t is a real number.
So just plug in any value for t to get another point. For example if you let t == 1 then the equation above reduces to point = B. If you let t = 0 then it reduces to point = A. So you can see that you can use this to find a point between A and B simply by let t range from 0 to 1. Additionally if you let t > 1, you will find a point past B.
You can see from the image that your given points are x1,y1 and x2,y2. You need to find an intermediate point at a distance 'R' from point x1,y1.
All you need to do is to find θ using
Tan θ = (y2-y1)/(x2-x1)
Then you can get the intermediate point as (R * cos θ),(R * Sin θ)
I have drawn this assuming positive slope.
Going on similar lines you can seek a solution for other special cases lile:
i. Horizontal line
ii. Vertical line
iii. Negative slope
Hope it clarifies.
I have done the calculation in Andengine using a Sprite object. I have two Array List x coordinates and y coordinates. Here i am just calculating using the last two values from these two array list to calculate the third point 800 pixel distant from Your point B. you can modify it using different values other than 800. Hope it will work.The coordinate system here is a little different where (0,0) on the top left corner of the screen. Thanks
private void addExtraCoordinate(CarSprite s) {
int x0, y0, x1, y1;
float x = 0f, y = 0f;
x0 = Math.round(xCoordinates.get(xCoordinates.size() - 2));
x1 = Math.round(xCoordinates.get(xCoordinates.size() - 1));
y0 = Math.round(yCoordinates.get(yCoordinates.size() - 2)) * (-1);
y1 = Math.round(yCoordinates.get(yCoordinates.size() - 1)) * (-1);
if (x1 == x0 && y1 == y0) {
return;
} else if (y1 == y0 && x1 != x0) {
if (x1 > x0) {
x = (float) x1 + 800f;
} else
x = (float) x1 - 800f;
y = Math.round(yCoordinates.get(yCoordinates.size() - 1));
} else if (y1 != y0 && x1 == x0) {
if (y1 > y0) {
y = (float) Math.abs(y1) - 800f;
} else
y = (float) Math.abs(y1) + 800f;
x = Math.round(xCoordinates.get(xCoordinates.size() - 1));
} else {
float m = (float) (yCoordinates.get(yCoordinates.size() - 1) * (-1) - yCoordinates
.get(yCoordinates.size() - 2) * (-1))
/ (float) (xCoordinates.get(xCoordinates.size() - 1) - xCoordinates
.get(xCoordinates.size() - 2));
if (x1 > x0) {
x = (float) ((float) x1 + 800f / (float) Math
.sqrt((double) ((double) 1f + (double) (m * m))));
} else
x = (float) ((float) x1 - 800f / (float) Math
.sqrt((double) ((double) 1f + (double) (m * m))));
if (y0 > y1) {
y = (float) ((float) Math.abs(y1) + 800f / (float) Math
.sqrt((double) (((double) 1f / (double) (m * m)) + (double) 1f)));
} else
y = (float) ((float) Math.abs(y1) - 800f / (float) Math
.sqrt((double) (((double) 1f / (double) (m * m)) + (double) 1f)));
}
xCoordinates.add(x);
yCoordinates.add(y);
}
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