Calculate a Point Along the Line A-B at a Given Distance from A

Caculating coordinates of specific point on the line

Here is a more mathematical approach: (I hope you understand my drawing)

enter image description here

You know A and B and the distance from A to C. The angle can be calculated by calculatin the slope of [AB]. From here you should be able to figure the lenght of the 2 segments (marked with blue), by using sin and cos.

Given a start and end point, and a distance, calculate a point along a line

I think this belongs on MathOverflow, but I'll answer since this is your first post.
First you calculate the vector from x1y1 to x2y2:

float vx = x2 - x1;
float vy = y2 - y1;

Then calculate the length:

float mag = sqrt(vx*vx + vy*vy);

Normalize the vector to unit length:

vx /= mag;
vy /= mag;

Finally calculate the new vector, which is x2y2 + vxvy * (mag + distance).

*px = (int)((float)x1 + vx * (mag + distance));
*py = (int)((float)y1 + vy * (mag + distance));

You can omit some of the calculations multiplying with distance / mag instead.

Calculate a point along a line segment one unit from a end of the seg

This is kind of hitting a nail with a sledge hammer, but if you're going to be running into geometry problems often, I'd either write or find a Point/Vector class like

import math
class Vector():
def __init__(self, x=0.0, y=0.0, z=0.0):
self.x = x
self.y = y
self.z = z

def __add__(self, other):
self.x += other.x
self.y += other.y
self.z += other.z
return self

def __sub__(self, other):
self.x -= other.x
self.y -= other.y
self.z -= other.z
return self

def dot(self, other):
return self.x*other.x + self.y*other.y + self.z*other.z

def cross(self, other):
tempX = self.y*other.z - self.z*other.y
tempY = self.z*other.x - solf.x*other.z
tempZ = self.x*other.y - self.y*other.x
return Vector(tempX, tempY, tempZ)

def dist(self, other):
return math.sqrt((self.x-other.x)**2 + (self.y-other.y)**2 + (self.z-other.z)**2)

def unitVector(self):
mag = self.dist(Vector())
if mag != 0.0:
return Vector(self.x * 1.0/mag, self.y * 1.0/mag, self.z * 1.0/mag)
else:
return Vector()

def __repr__(self):
return str([self.x, self.y, self.z])

Then you can do all kinds of stuff like find the vector by subtracting two points

>>> a = Vector(4,5,0)
>>> b = Vector(5,6,0)
>>> b - a
[1, 1, 0]

Or adding an arbitrary unit vector to a point to find a new point (which is the answer to your original question)

>>> a = Vector(4,5,0)
>>> direction = Vector(10, 1, 0).unitVector()
>>> a + direction
[4.995037190209989, 5.099503719020999, 0.0]

You can add more utilities, like allowing Vector/Scalar operations for scaling, etc.

How to find a point in 3-D at an arbitrary perpendicular line given distance to the point

If the desired point C can be any of the infinitely-many points fitting your requirements, here is one method.

Choose any vector that is not parallel or anti-parallel to vector AB. You could try the vector (1, 0, 0), and if that is parallel you could use (0, 1, 0) instead. Then take the cross-product of vector AB and the chosen vector. That cross-product is perpendicular to vector AB. Divide that cross-product by its length then multiply by the desired length N. Finally extend that vector from point B to find your desired point C.

Here is code in Python 3 that follows that algorithm. This code is somewhat non-pythonic to make it easier to convert to other languages. (If I really did this for myself I would use the numpy module to avoid coordinates completely and shorten this code.) But it does treat the points as tuples of 3 values: many languages will require you to handle each coordinate separately. Any real-life code would need to check for "near zero" rather than "zero" and to check that the sqrt calculation does not result in zero. I'll leave those additional steps to you. Ask if you have more questions.

from math import sqrt

def pt_at_given_distance_from_line_segment_and_endpoint(a, b, dist):
"""Return a point c such that line segment bc is perpendicular to
line segment ab and segment bc has length dist.

a and b are tuples of length 3, dist is a positive float.
"""
vec_ab = (b[0]-a[0], b[1]-a[1], b[2]-a[2])
# Find a vector not parallel or antiparallel to vector ab
if vec_ab[1] != 0 or vec_ab[2] != 0:
vec = (1, 0, 0)
else:
vec = (0, 1, 0)
# Find the cross product of the vectors
cross = (vec_ab[1] * vec[2] - vec_ab[2] * vec[1],
vec_ab[2] * vec[0] - vec_ab[0] * vec[2],
vec_ab[0] * vec[1] - vec_ab[1] * vec[0])
# Find the vector in the same direction with length dist
factor = dist / sqrt(cross[0]**2 + cross[1]**2 + cross[2]**2)
newvec = (factor * cross[0], factor * cross[1], factor * cross[2])
# Find point c such that vector bc is that vector
c = (b[0] + newvec[0], b[1] + newvec[1], b[2] + newvec[2])
# Done!
return c

The resulting output from the command

print(pt_at_given_distance_from_line_segment_and_endpoint((1, 2, 3), (4, 5, 6), 2))

is

(4.0, 6.414213562373095, 4.585786437626905)

Find Point on a line based on 3rd point tangent to that line

If a line is known by the equation A*x+B*y+C=0 and a point P is outside the line with coordinates (P_x,P_y) then the point on the line closest to P is

x = (A^2*P_y-A*B*P_x-B*C)/(A^2+B^2)
y = (B^2*P_x-A*B*P_y-A*C)/(A^2+B^2)

Also the minimum distance of point P to the line is

d = ABS(A*P_x+B*P_y+C)/SQRT(A^2+B^2)

Edit 1

The equation of an infinite line passing through two points (x_1,y_1) and (x_2,y_2) is

A*x+B*x+C=0
(y_1-y_2)*x + (x_2-x_1)*y + (x_1*y_2-x_2*y_1) = 0

Edit 2

If the line is given from point (Q_x,Q_y) and direction (e_x,e_y) then the equation coefficients are

A = -e_y
B = e_x
C = Q_x*e_y - Q_y*e_x


Related Topics



Leave a reply



Submit