Minimum Distance between a Point and a Line
Hi,
I know this is a simple geometry question and should have alot of people written java program for it before, but a search on google reveal no result that will do this.
Bascially I just want to find the Minimum Distance between a Point and a Line.
Point object {
int x, y;
}
Line object{
point p1;
point p2;
}
Any one know any library or script that do this function?
Here is what it should do:
http://local.wasp.uwa.edu.au/~pbourke/geometry/pointline/
This comes up every few months. The following code has been published by me in these forums several times.
package me.sabre150.research.howto.swing;
import java.awt.*;
import javax.swing.*;
public class FindTheClosesPointOnALine extends JFrame
{
public FindTheClosesPointOnALine()
{
super("Find The Closes Point On A Line");
this.getContentPane().setLayout(new BorderLayout());
this.setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
MyCanvas canvas = new MyCanvas();
canvas.setOpaque(true);
canvas.setBackground(Color.WHITE);
this.getContentPane().add(canvas, BorderLayout.CENTER);
this.setSize(700, 700);
}
class MyCanvas extends JPanel
{
Point pt1 = new Point(10, 20);
Point pt2 = new Point(200, 400);
double r = 300;
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.translate(200, 100);
g.setColor(Color.green);
g.drawLine(pt1.x, pt1.y, pt2.x, pt2.y);
for (double theta = 0.0; theta <2.0*Math.PI; theta += 0.11)
{
Point p = new Point((int)(Math.sin(theta)*r+0.5)+100, (int)(Math.cos(theta)*r+0.5)+200);
g.setColor(isWithinRadius(pt2, pt1, p, false, 0.9 * r) ? Color.blue : Color.red);
Point q = myGetClosestPoint(pt2, pt1, p, false);
g.drawLine(q.x, q.y, p.x, p.y);
}
}
}
public static void main(String[] args)
{
new FindTheClosesPointOnALine().setVisible(true);
}
/**
* Finds the point closest to a point 'p' on the line
* between two points 'pt1' and 'pt2'.
*
*[pt2]
* /
*[p] /
* #/
* #/
*c Closest point
*/
*/
* /
* /
*/
*/
* /
* /
*[pt1]
*
* @param pt1 one end of the line
* @param pt2 the other end of the line
* @param p the point to find the closest point to.
* @param allowOnExtension <code>true</code> if the calculated
* point may be located outside the bounds defind by 'pt1' and 'pt2'.
* @return the point closest to a point 'p' on the line
* between two points 'pt1' and 'pt2'.
*/
private static Point myGetClosestPoint(Point pt1, Point pt2, Point p, boolean allowOnExtension)
{
// If the two points represent the same point then
// they are the closest point.
if (pt1.equals(pt2))
return (Point)pt1.clone();
// Compute the relative position of the closest point to the point 'p'
// u = ((p - pt1) . (pt2 - pt1)) / ((pt2 - pt1) . (pt2 - pt1))
// where '.' is the vector dot product
double u = ((p.x-pt1.x)*(pt2.x-pt1.x)+(p.y-pt1.y)*(pt2.y-pt1.y))/(sqr(pt2.x-pt1.x)+sqr(pt2.y-pt1.y));
// Remove this conditional statement if you allow the closest point to be
// exterior to the direct line between pt1 and pt2.
if (!allowOnExtension)
{
if (u >= 1.0)
return (Point)pt2.clone();
else if (u <= 0.0)
return (Point)pt1.clone();
}
// Create the closest point
return new Point(round(pt2.x * u + pt1.x * (1.0 - u)), round(pt2.y * u + pt1.y * (1.0 - u)));
}
private static double distanceToClosestPoint(Point pt1, Point pt2, Point p, boolean allowOnExtension)
{
Point pt0 = myGetClosestPoint(pt1, pt2, p, allowOnExtension);
return Math.sqrt(sqr(p.x - pt0.x) + sqr(p.y - pt0.y));
}
private static boolean isWithinRadius(Point pt1, Point pt2, Point p, boolean allowOnExtension, double radius)
{
assert radius > 0.0;
Point pt0 = myGetClosestPoint(pt1, pt2, p, allowOnExtension);
return (sqr(p.x - pt0.x) + sqr(p.y - pt0.y)) <= sqr(radius);
}
private static double sqr(double x)
{
return x*x;
}
private static int round(double v)
{
return (int)(v+0.5);
}
}