I often need to construct perpendiculars in my code and found a very elegant solution to this problem in CGAL source.
Given points A(xa, ya) and B(xb, yb), perpendiculars BBccw and BBcw to the line AB can be constructed at B using either of the following points:
Bccw(xb – (yb – ya), yb + (xb – xa)) // such that ABBccw is oriented counter-clockwise
or
Bcw(xb + (yb – ya), yb – (xb – xa)) // such that ABBcw is clockwise.
This follows from the fact that the product of the slopes of perpendicular lines is -1.
Here is code to return either of these points.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
#include struct P2 { float x; float y; P2(float x, float y) : x(x), y(y) { } }; P2 PerpendicularCW(const P2& a, const P2& b){ return P2(b.x + (b.y - a.y), b.y - (b.x - a.x)); } P2 PerpendicularCCW(const P2& a, const P2& b){ return P2(b.x - (b.y - a.y), b.y + (b.x - a.x)); } int main(){ P2 a(20, 20), b(80, 60); P2 pccw = PerpendicularCCW(a, b); P2 pcw = PerpendicularCW(a, b); printf("a(%f,%f),b(%f,%f)\n";, a.x, a.y, b.x, b.y); printf("pccw(%f,%f)\n", pccw.x, pccw.y); printf("pcw(%f,%f)\n", pcw.x, pcw.y); return 0; } |
Output:
1 2 3 |
a(20.000000,20.000000),b(80.000000,60.000000) pccw(120.000000,0.000000) pcw(40.000000,120.000000) |