From: | Kyotaro HORIGUCHI <horiguchi(dot)kyotaro(at)lab(dot)ntt(dot)co(dot)jp> |
---|---|
To: | pgsql-hackers(at)postgresql(dot)org |
Subject: | line_perp() (?-|) is broken. |
Date: | 2018-02-01 11:51:38 |
Message-ID: | 20180201.205138.34583581.horiguchi.kyotaro@lab.ntt.co.jp |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-hackers |
I happend to see a strange geometric calcualtion on master/HEAD.
CREATE TABLE t (l1 line, l2 line);
INSERT INTO t
(SELECT line(point(0, 0), point(x, y)), line(point(0,0), point(-y, x))
FROM (SELECT random() x, random() y FROM generate_series(0, 1000)) AS a);
SELECT l1?-|l2 AS is_perp, l1, l2 FROM t;
is_perp | l1 | l2
---------+----------------------------+-----------------------------
f | {0.215980373614968,-1,0} | {-4.63005032940037,-1,0}
f | {1.51653638154567,-1,0} | {-0.659397303070824,-1,0}
f | {0.596861744826871,-1,0} | {-1.67542987746696,-1,0}
...
SELECT l1?-|l2 AS is_perp, l1, l2 FROM t WHERE l1?-|l2;
is_perp | l1 | l2
---------+----+----
(0 rows)
The two lines in a row are always perpendicular, but ?-| doesn't
agree.
line_perp() is working with the following arithmetic.
(l1->A * l2->B) / (l1->B * l2->A) == -1.0
or
(l1->A * l2->B) + (l1->B * l2->A) == 0
If the plus were a minus, it would calculate the cross product of
the two vectors and tell if the two lines are "parallel" or
not... Anyway it doesn't work as expected. At least back to 9.0
has the same expression in the function.
Instead, calculating inner product of the two direction vectors
works as expected.
(l1->A * l2->A) + (l1->B * l2->B) == 0
FPzero checks at the beggining of the function for the purpose of
avoiding div0 is useless with this form of expression.
With the attached patch, we will have the correct result.
is_perp | l1 | l2
---------+----------------------------+-----------------------------
t | {0.215980373614968,-1,0} | {-4.63005032940037,-1,0}
t | {1.51653638154567,-1,0} | {-0.659397303070824,-1,0}
t | {0.596861744826871,-1,0} | {-1.67542987746696,-1,0}
t | {2.14739225724798,-1,0} | {-0.465681105361517,-1,0}
...
SELECT l1?-|l2 AS is_perp, l1, l2 FROM t WHERE NOT l1?-|l2;
is_perp | l1 | l2
---------+----+----
(0 rows)
regards.
Attachment | Content-Type | Size |
---|---|---|
fix_line_perp.patch | text/x-patch | 565 bytes |
From | Date | Subject | |
---|---|---|---|
Next Message | Kyotaro HORIGUCHI | 2018-02-01 11:52:10 | Re: [HACKERS] [PATCH] Improve geometric types |
Previous Message | Simon Riggs | 2018-02-01 11:07:49 | Re: [HACKERS] MERGE SQL Statement for PG11 |