TheSwamp
Code Red => .NET => Topic started by: huiz on May 26, 2011, 03:19:19 PM
-
I've not seen a school from inside the last 20 years (besides kindergarten where my kids are playing around) and I did not pay much attention when I had math lessons... So who can help me with a formula?
I have 3 points (Point2D objects), let's say A, B and C. I have an imaginary line between A and B. I want to project C on the line A-B (C can be before A or after B on that line) and I would like to know the coordinates of the projected point C. And all that in plain VB or C#.
I know I could draw two rays, get the intersection and remove the rays but there is some formula for. Anyone with a quick help? :-)
-
I would use the vector dot product of the vector AC and the unit vector AB, this will give you the distance of the projection of C along AB as measured from A
-
Here is a great resources for catching back up on math http://www.theswamp.org/index.php?topic=37552.0
*********Edit*******
Link to the videos http://www.khanacademy.org/#browse
-
Have you looked at Curve.GetClosestPointTo()...?
-
Another, using a crafty coordinate transformation:
(defun LM:ClosestPointToLine ( pt p1 p2 / n )
(setq n (mapcar '- p2 p1)
p1 (trans p1 0 n) pt (trans pt 0 n)
)
(trans (list (car p1) (cadr p1) (caddr pt)) n 0)
)
pt - given point
p1 - first point of line
p2 - second point of line
:wink:
-
Public Shared Sub ClosestPointOnSegmentFromPoint(ByVal x1 As Double, _
ByVal y1 As Double, _
ByVal x2 As Double, _
ByVal y2 As Double, _
ByVal px As Double, _
ByVal py As Double, _
ByRef nx As Double, _
ByRef ny As Double)
Dim vx As Double = x2 - x1
Dim vy As Double = y2 - y1
Dim wx As Double = px - x1
Dim wy As Double = py - y1
Dim c1 As Double = vx * wx + vy * wy
If c1 <= 0# Then
nx = x1
ny = y1
Return
End If
Dim c2 As Double = vx * vx + vy * vy
If c2 <= c1 Then
nx = x2
ny = y2
Return
End If
Dim Ratio As Double = c1 / c2
nx = x1 + ratio * vx
ny = y1 + ratio * vy
End Sub
Public Shared Sub ClosestPointOnSegmentFromPoint(ByVal x1 As Double, _
ByVal y1 As Double, _
ByVal z1 As Double, _
ByVal x2 As Double, _
ByVal y2 As Double, _
ByVal z2 As Double, _
ByVal px As Double, _
ByVal py As Double, _
ByVal pz As Double, _
ByRef nx As Double, _
ByRef ny As Double, _
ByRef nz As Double)
Dim vx As Double = x2 - x1
Dim vy As Double = y2 - y1
Dim vz As Double = z2 - z1
Dim wx As Double = px - x1
Dim wy As Double = py - y1
Dim wz As Double = pz - z1
Dim c1 As Double = vx * wx + vy * wy + vz * wz
If c1 <= 0# Then
nx = x1
ny = y1
nz = z1
Return
End If
Dim c2 As Double = vx * vx + vy * vy + vz * vz
If c2 <= c1 Then
nx = x2
ny = y2
nz = z2
Return
End If
Dim ratio As Double = c1 / c2
nx = x1 + ratio * vx
ny = y1 + ratio * vy
nz = z1 + ratio * vz
End Sub
-
Hi,
Using the dot product, returns the 'pt' point projection on 'p1 p2' unbounded line.
private Point3d ProjectPointOnLine(Point3d pt, Point3d p1, Point3d p2)
{
Vector3d v1 = p1.GetVectorTo(p2);
Vector3d v2 = p1.GetVectorTo(pt);
double scale = v1.DotProduct(v2) / p1.DistanceTo(p2);
return p1 + v1.GetNormal().MultiplyBy(scale);
}
-
Wow, all different solutions :-) Thanks all! I will play with all this to find out which is the best for me.
I had searched Google first but after 3 hours of examing complicated formulas I quit.
-
Hi,
Returns the point or distance perpendicular to the direction formed by two points.
/// <summary>
/// Devuelve el punto o distancia perpendicular a la direccion formada por dos puntos.
/// </summary>
/// <param name="pto">Punto a calcular.</param>
/// <param name="p1">Primer punto alineación.</param>
/// <param name="p2">Segundo punto alineación.</param>
/// <param name="modo">[True] punto, [False] distancia.</param>
/// <returns></returns>
static internal object PntPrpndclr(Point3d pto, Point3d p1, Point3d p2, bool modo)
{
Vector3d vect1 = pto.GetVectorTo(p1);
Vector3d vect2 = vect1.GetPerpendicularVector();
Plane plano = new Plane(pto, vect1, vect2);
Point3d pt = p2.OrthoProject(plano);
if (modo == true){return pt;}else{return pt.DistanceTo(pto);}
}
-
The same as in reply #6 in a more concise way.
private Point3d ProjectPointOnLine(Point3d pt, Point3d p1, Point3d p2)
{
Vector3d vect = (p2 - p1).GetNormal();
return p1 + vect * vect.DotProduct(pt - p1);
}
-
But IMO the simplest way is to use a Geometry.Line3d instance and the Curve3d.GetClosestPont method.
private Point3d ProjectPointOnLine(Point3d pt, Point3d p1, Point3d p2)
{
return new Line3d(p1, p2).GetClosestPointTo(pt).Point;
}
-
But IMO the simplest way is to use a Geometry.Line3d instance and the Curve3d.GetClosestPont method.
private Point3d ProjectPointOnLine(Point3d pt, Point3d p1, Point3d p2)
{
return new Line3d(p1, p2).GetClosestPointTo(pt).Point;
}
Simplicity has power!!! :)
Gile, you are brilliant! This function works great and it is really simple. Thanks for your advice! :-)
-
Guess I was a little too vague, eh? ;-)
-
Guess I was a little too vague, eh? ;-)
Hehe :) Not really, I had in mind to examine this one too but at first sight I thought this routine would give back the closest node of a line. I still had in mind that a mathematical formula was the best way till I saw the routine of Gile. Then I tried that and found out that this returned a perpendicular point instead of the nearest point. You also thanks, if Gile didn't post his solution I would find out your solution after I got stuck with complicated formulas :)
-
Then I tried that and found out that this returned a perpendicular point instead of the nearest point.
Replace 'instead of' with 'which is, of course,' ;-)
-
I'am sorry. It's easier for me to give some lines of code rather than a good explaination in English even i know it's not 'educational'.
Sinc gave the way for the GetClosestPointTo() route, I only wanted to show there was no need to draw two rays.
And Lee talk about the dot product way before I posted the codes.
-
Yes, but with a full function in front of me I got the message.
Because I assumed the nearest point would return the nearest vertex of a line.
-
Yes, but with a full function in front of me I got the message.
Because I assumed the nearest point would return the nearest vertex of a line.
Look at the code, it uses a Geometry.Line3d instance which has none vertex: it is unbounded.
The Geometry namespace contains plenty of classes (such as points, lines, segments, circular arcs, vectors, matrices, and so on) which aren't DBObject and are provided to solve geometry issues.