I often need to construct perpendiculars in my code and found a very elegant solution to this problem in CGAL source.

Given points A(x_{a}, y_{a}) and B(x_{b}, y_{b}), perpendiculars BB_{ccw} and BB_{cw} to the line AB can be constructed at B using either of the following points:

B_{ccw}(x_{b} – (y_{b} – y_{a}), y_{b} + (x_{b} – x_{a})) // such that ABB_{ccw} is oriented counter-clockwise

or

B_{cw}(x_{b} + (y_{b} – y_{a}), y_{b} – (x_{b} – x_{a})) // such that ABB_{cw} 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) |