blob: 582ca471b97fcb0ac940083c0d9a307cd24dda6a [file] [log] [blame]
caryclark@google.com639df892012-01-10 21:46:10 +00001#include "DataTypes.h"
2
3// Sources
4// computer-aided design - volume 22 number 9 november 1990 pp 538 - 549
5// online at http://cagd.cs.byu.edu/~tom/papers/bezclip.pdf
6
caryclark@google.comb45a1b42012-05-18 20:50:33 +00007// This turns a line segment into a parameterized line, of the form
8// ax + by + c = 0
9// When a^2 + b^2 == 1, the line is normalized.
10// The distance to the line for (x, y) is d(x,y) = ax + by + c
11//
12// Note that the distances below are not necessarily normalized. To get the true
13// distance, it's necessary to either call normalize() after xxxEndPoints(), or
14// divide the result of xxxDistance() by sqrt(normalSquared())
15
caryclark@google.com639df892012-01-10 21:46:10 +000016class LineParameters {
17public:
18 void cubicEndPoints(const Cubic& pts) {
19 a = pts[0].y - pts[3].y;
20 b = pts[3].x - pts[0].x;
21 c = pts[0].x * pts[3].y - pts[3].x * pts[0].y;
22 }
rmistry@google.comd6176b02012-08-23 18:14:13 +000023
caryclark@google.com639df892012-01-10 21:46:10 +000024 void cubicEndPoints(const Cubic& pts, int s, int e) {
25 a = pts[s].y - pts[e].y;
26 b = pts[e].x - pts[s].x;
27 c = pts[s].x * pts[e].y - pts[e].x * pts[s].y;
28 }
rmistry@google.comd6176b02012-08-23 18:14:13 +000029
caryclark@google.com639df892012-01-10 21:46:10 +000030 void lineEndPoints(const _Line& pts) {
31 a = pts[0].y - pts[1].y;
32 b = pts[1].x - pts[0].x;
33 c = pts[0].x * pts[1].y - pts[1].x * pts[0].y;
34 }
rmistry@google.comd6176b02012-08-23 18:14:13 +000035
caryclark@google.com639df892012-01-10 21:46:10 +000036 void quadEndPoints(const Quadratic& pts) {
37 a = pts[0].y - pts[2].y;
38 b = pts[2].x - pts[0].x;
39 c = pts[0].x * pts[2].y - pts[2].x * pts[0].y;
40 }
41
42 void quadEndPoints(const Quadratic& pts, int s, int e) {
43 a = pts[s].y - pts[e].y;
44 b = pts[e].x - pts[s].x;
45 c = pts[s].x * pts[e].y - pts[e].x * pts[s].y;
46 }
47
48 double normalSquared() {
49 return a * a + b * b;
50 }
51
52 bool normalize() {
53 double normal = sqrt(normalSquared());
caryclark@google.comb45a1b42012-05-18 20:50:33 +000054 if (approximately_zero_squared(normal)) {
caryclark@google.com639df892012-01-10 21:46:10 +000055 a = b = c = 0;
56 return false;
57 }
58 double reciprocal = 1 / normal;
59 a *= reciprocal;
60 b *= reciprocal;
61 c *= reciprocal;
62 return true;
63 }
rmistry@google.comd6176b02012-08-23 18:14:13 +000064
caryclark@google.com639df892012-01-10 21:46:10 +000065 void cubicDistanceY(const Cubic& pts, Cubic& distance) {
66 double oneThird = 1 / 3.0;
67 for (int index = 0; index < 4; ++index) {
68 distance[index].x = index * oneThird;
69 distance[index].y = a * pts[index].x + b * pts[index].y + c;
70 }
71 }
72
73 void quadDistanceY(const Quadratic& pts, Quadratic& distance) {
74 double oneHalf = 1 / 2.0;
75 for (int index = 0; index < 3; ++index) {
76 distance[index].x = index * oneHalf;
77 distance[index].y = a * pts[index].x + b * pts[index].y + c;
78 }
79 }
80
81 void controlPtDistance(const Cubic& pts, double distance[2]) {
82 for (int index = 0; index < 2; ++index) {
83 distance[index] = a * pts[index + 1].x + b * pts[index + 1].y + c;
84 }
85 }
rmistry@google.comd6176b02012-08-23 18:14:13 +000086
caryclark@google.com639df892012-01-10 21:46:10 +000087 void controlPtDistance(const Cubic& pts, int i, int j, double distance[2]) {
88 distance[0] = a * pts[i].x + b * pts[i].y + c;
89 distance[1] = a * pts[j].x + b * pts[j].y + c;
90 }
rmistry@google.comd6176b02012-08-23 18:14:13 +000091
caryclark@google.com639df892012-01-10 21:46:10 +000092 double controlPtDistance(const Quadratic& pts) {
93 return a * pts[1].x + b * pts[1].y + c;
94 }
rmistry@google.comd6176b02012-08-23 18:14:13 +000095
caryclark@google.com639df892012-01-10 21:46:10 +000096 double pointDistance(const _Point& pt) {
97 return a * pt.x + b * pt.y + c;
98 }
caryclark@google.comb45a1b42012-05-18 20:50:33 +000099
caryclark@google.com639df892012-01-10 21:46:10 +0000100private:
101 double a;
102 double b;
103 double c;
104};