Xazker's blog

By Xazker, 15 years ago, translation, In English
I always thought that standard libraries work not so fast, but at least correctly. It was really surprise, to see such strange results from code given below.
java.awt.geom 
Class Line2D

ptLineDist

public static double ptLineDist(double X1,
                                double Y1,
                                double X2,
                                double Y2,
                                double PX,
                                double PY)

Returns the distance from a point to a line. The distance measured is the distance between the specified point and the closest point on the infinitely-extended line defined by the specified coordinates. If the specified point intersects the line, this method returns 0.0.

System.out.println(Line2D.ptLineDist(0, 0, 1, 200, 1, 199));
System.out.println(Line2D.ptLineDist(0, 0, 1, 2000, 1, 1999));
System.out.println(Line2D.ptLineDist(0, 0, 1, 20000, 1, 19999));
System.out.println(Line2D.ptLineDist(0, 0, 1, 200000, 1, 199999));
System.out.println(Line2D.ptLineDist(0, 0, 1, 2000000, 1, 1999999));
System.out.println(Line2D.ptLineDist(0, 0, 1, 20000000, 1, 19999999));


0.004999937545118085
5.000601076713239E-4
0.0                                      --- the distance from point (1,19999) to line (0,0) (1, 20000) equals 0 !!!
0.0
0.0
0.25                                    --- no sense

Who can explain that?
  • Vote: I like it
  • +7
  • Vote: I do not like it

15 years ago, # |
  Vote: I like it +3 Vote: I do not like it
I think the standard libraries about ptLineDist is not good;

this is the ptLineDist source code;


public static double
ptLineDistSq (double X1, double Y1,
                      double X2, double Y2,
                      double PX, double PY) {
 
X2 -= X1;
     Y2 -= Y1;
 
PX -= X1;
     PY -= Y1;
     double dotprod = PX * X2 + PY * Y2;
   
double projlenSq = dotprod * dotprod / (X2 * X2 + Y2 * Y2);
   
double lenSq = PX * PX + PY * PY - projlenSq;
   
if (lenSq < 0) {
         
lenSq = 0;
    }
   
return lenSq;
}

public static double ptLineDist (double X1, double Y1,
                      double X2, double Y2,
                      double PX, double PY) {
    return
return Math.sqrt(ptLineDistSq(X1, Y1, X2, Y2, PX, PY));
}

in the method
ptLineDistSq java stander use dot-product to calculate the dist.
and use dot*dot this maybe as larger as x^4,but
(X2 * X2 + Y2 * Y2) is x^2;
so the result
projlenSq could be make a flat error,and make lenSq could be very small,even to zero.

you can try write a new method use cross-product,then you will find it come up with the correct answer:
    public static double pointToLineDist(Point p,Point A,Point B)
    {
        return Math.abs(p.sub(A).cross(B.sub(A))/B.sub(A).len());
    }


15 years ago, # |
  Vote: I like it +3 Vote: I do not like it
I think the standard libraries about ptLineDist is not good;

this is the ptLineDist source code;


public static double
ptLineDistSq (double X1, double Y1,
                      double X2, double Y2,
                      double PX, double PY) {
 
X2 -= X1;
     Y2 -= Y1;
 
PX -= X1;
     PY -= Y1;
     double dotprod = PX * X2 + PY * Y2;
   
double projlenSq = dotprod * dotprod / (X2 * X2 + Y2 * Y2);
   
double lenSq = PX * PX + PY * PY - projlenSq;
   
if (lenSq < 0) {
         
lenSq = 0;
    }
   
return lenSq;
}

public static double ptLineDist (double X1, double Y1,
                      double X2, double Y2,
                      double PX, double PY) {
    return
return Math.sqrt(ptLineDistSq(X1, Y1, X2, Y2, PX, PY));
}

in the method
ptLineDistSq java stander use dot-product to calculate the dist.
and use dot*dot this maybe as larger as x^4,but
(X2 * X2 + Y2 * Y2) is x^2;
so the result
projlenSq could be make a flat error,and make lenSq could be very small,even to zero.

you can try write a new method use cross-product,then you will find it come up with the correct answer:
    public static double pointToLineDist(Point p,Point A,Point B)
    {
        return Math.abs(p.sub(A).cross(B.sub(A))/B.sub(A).len());
    }


15 years ago, # |
  Vote: I like it +6 Vote: I do not like it
I think the standard libraries about ptLineDist is not good;

this is the ptLineDist source code;


public static double
ptLineDistSq (double X1, double Y1,
                      double X2, double Y2,
                      double PX, double PY) {
 
X2 -= X1;
     Y2 -= Y1;
 
PX -= X1;
     PY -= Y1;
     double dotprod = PX * X2 + PY * Y2;
   
double projlenSq = dotprod * dotprod / (X2 * X2 + Y2 * Y2);
   
double lenSq = PX * PX + PY * PY - projlenSq;
   
if (lenSq < 0) {
         
lenSq = 0;
    }
   
return lenSq;
}

public static double ptLineDist (double X1, double Y1,
                      double X2, double Y2,
                      double PX, double PY) {
    return
return Math.sqrt(ptLineDistSq(X1, Y1, X2, Y2, PX, PY));
}

in the method
ptLineDistSq java stander use dot-product to calculate the dist.
and use dot*dot this maybe as larger as x^4,but
(X2 * X2 + Y2 * Y2) is x^2;
so the result
projlenSq could be make a flat error,and make lenSq could be very small,even to zero.

you can try write a new method use cross-product,then you will find it come up with the correct answer:
    public static double pointToLineDist(Point p,Point A,Point B)
    {
        return Math.abs(p.sub(A).cross(B.sub(A))/B.sub(A).len());
    }


15 years ago, # |
  Vote: I like it 0 Vote: I do not like it
I think the standard libraries about ptLineDist is not good;

this is the ptLineDist source code;


public static double
ptLineDistSq (double X1, double Y1,
                      double X2, double Y2,
                      double PX, double PY) {
 
X2 -= X1;
     Y2 -= Y1;
 
PX -= X1;
     PY -= Y1;
     double dotprod = PX * X2 + PY * Y2;
   
double projlenSq = dotprod * dotprod / (X2 * X2 + Y2 * Y2);
   
double lenSq = PX * PX + PY * PY - projlenSq;
   
if (lenSq < 0) {
         
lenSq = 0;
    }
   
return lenSq;
}

public static double ptLineDist (double X1, double Y1,
                      double X2, double Y2,
                      double PX, double PY) {
    return
return Math.sqrt(ptLineDistSq(X1, Y1, X2, Y2, PX, PY));
}

in the method
ptLineDistSq java stander use dot-product to calculate the dist.
and use dot*dot this maybe as larger as x^4,but
(X2 * X2 + Y2 * Y2) is x^2;
so the result
projlenSq could be make a flat error,and make lenSq could be very small,even to zero.

you can try write a new method use cross-product,then you will find it come up with the correct answer:
    public static double pointToLineDist(Point p,Point A,Point B)
    {
        return Math.abs(p.sub(A).cross(B.sub(A))/B.sub(A).len());
    }


15 years ago, # |
  Vote: I like it 0 Vote: I do not like it
I think the standard libraries about ptLineDist is not good;

this is the ptLineDist source code;


public static double
ptLineDistSq (double X1, double Y1,
                      double X2, double Y2,
                      double PX, double PY) {
 
X2 -= X1;
     Y2 -= Y1;
 
PX -= X1;
     PY -= Y1;
     double dotprod = PX * X2 + PY * Y2;
   
double projlenSq = dotprod * dotprod / (X2 * X2 + Y2 * Y2);
   
double lenSq = PX * PX + PY * PY - projlenSq;
   
if (lenSq < 0) {
         
lenSq = 0;
    }
   
return lenSq;
}

public static double ptLineDist (double X1, double Y1,
                      double X2, double Y2,
                      double PX, double PY) {
    return
return Math.sqrt(ptLineDistSq(X1, Y1, X2, Y2, PX, PY));
}

in the method
ptLineDistSq java stander use dot-product to calculate the dist.
and use dot*dot this maybe as larger as x^4,but
(X2 * X2 + Y2 * Y2) is x^2;
so the result
projlenSq could be make a flat error,and make lenSq could be very small,even to zero.

you can try write a new method use cross-product,then you will find it come up with the correct answer:
    public static double pointToLineDist(Point p,Point A,Point B)
    {
        return Math.abs(p.sub(A).cross(B.sub(A))/B.sub(A).len());
    }


15 years ago, # |
  Vote: I like it 0 Vote: I do not like it
I think the standard libraries about ptLineDist is not good;

this is the ptLineDist source code;


public static double
ptLineDistSq (double X1, double Y1,
                      double X2, double Y2,
                      double PX, double PY) {
 
X2 -= X1;
     Y2 -= Y1;
 
PX -= X1;
     PY -= Y1;
     double dotprod = PX * X2 + PY * Y2;
   
double projlenSq = dotprod * dotprod / (X2 * X2 + Y2 * Y2);
   
double lenSq = PX * PX + PY * PY - projlenSq;
   
if (lenSq < 0) {
         
lenSq = 0;
    }
   
return lenSq;
}

public static double ptLineDist (double X1, double Y1,
                      double X2, double Y2,
                      double PX, double PY) {
    return
return Math.sqrt(ptLineDistSq(X1, Y1, X2, Y2, PX, PY));
}

in the method
ptLineDistSq java stander use dot-product to calculate the dist.
and use dot*dot this maybe as larger as x^4,but
(X2 * X2 + Y2 * Y2) is x^2;
so the result
projlenSq could be make a flat error,and make lenSq could be very small,even to zero.

you can try write a new method use cross-product,then you will find it come up with the correct answer:
    public static double pointToLineDist(Point p,Point A,Point B)
    {
        return Math.abs(p.sub(A).cross(B.sub(A))/B.sub(A).len());
    }


15 years ago, # |
  Vote: I like it 0 Vote: I do not like it
I think the standard libraries about ptLineDist is not good;

this is the ptLineDist source code;


public static double
ptLineDistSq (double X1, double Y1,
                      double X2, double Y2,
                      double PX, double PY) {
 
X2 -= X1;
     Y2 -= Y1;
 
PX -= X1;
     PY -= Y1;
     double dotprod = PX * X2 + PY * Y2;
   
double projlenSq = dotprod * dotprod / (X2 * X2 + Y2 * Y2);
   
double lenSq = PX * PX + PY * PY - projlenSq;
   
if (lenSq < 0) {
         
lenSq = 0;
    }
   
return lenSq;
}

public static double ptLineDist (double X1, double Y1,
                      double X2, double Y2,
                      double PX, double PY) {
    return
return Math.sqrt(ptLineDistSq(X1, Y1, X2, Y2, PX, PY));
}

in the method
ptLineDistSq java stander use dot-product to calculate the dist.
and use dot*dot this maybe as larger as x^4,but
(X2 * X2 + Y2 * Y2) is x^2;
so the result
projlenSq could be make a flat error,and make lenSq could be very small,even to zero.

you can try write a new method use cross-product,then you will find it come up with the correct answer:
    public static double pointToLineDist(Point p,Point A,Point B)
    {
        return Math.abs(p.sub(A).cross(B.sub(A))/B.sub(A).len());
    }


  • 15 years ago, # ^ |
      Vote: I like it 0 Vote: I do not like it
    May be i don't understand something, but i think there is a mistake. For example if A = (0, 0) B = (10, 0) and p = (3, 2)
    we get
    p.sub(A) = (3, 2)
    B.sub(A) = (10, 0)
    p.sub(A).cross(B.sub(A)) = 3 * 10 + 0 * 2 = 30
    p.sub(A).cross(B.sub(A)) / (B.sub(A).len()) = 30 / 10 = 3

    but real answer is 2. How to fix that?
15 years ago, # |
  Vote: I like it 0 Vote: I do not like it
Oh, it was my fault. I mixed up cross and dot product. :)
  • 15 years ago, # ^ |
      Vote: I like it 0 Vote: I do not like it
    - -!
    Why there are so many reply by me.

    P.S. wow,your photo is a cat.My ID is a cat too(cat=mao).
    • 15 years ago, # ^ |
        Vote: I like it 0 Vote: I do not like it
      I had this issue when I was using Opera, it's probably a bug. What browser do you use?

      P. S. Are you on your avatar? :)
      • 15 years ago, # ^ |
          Vote: I like it 0 Vote: I do not like it
        I use Firefox。

        P.S. I'm not a girl.- -!
        • 15 years ago, # ^ |
            Vote: I like it 0 Vote: I do not like it
          What a pity!
          Well, you must have pressed the submit button several times, then.
          • 15 years ago, # ^ |
              Vote: I like it 0 Vote: I do not like it
            Satyr!
            May be I pressed but it didn't work,so I pressed several times.
            - -!