blob: 2678f819b443da2d3cb0c4267e81359778e8496e [file] [log] [blame]
caryclark@google.com9e49fb62012-08-27 14:11:33 +00001/*
2 * Copyright 2012 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
caryclark@google.com639df892012-01-10 21:46:10 +00007#include "DataTypes.h"
8
9// Sources
10// computer-aided design - volume 22 number 9 november 1990 pp 538 - 549
11// online at http://cagd.cs.byu.edu/~tom/papers/bezclip.pdf
12
caryclark@google.comb45a1b42012-05-18 20:50:33 +000013// This turns a line segment into a parameterized line, of the form
14// ax + by + c = 0
15// When a^2 + b^2 == 1, the line is normalized.
16// The distance to the line for (x, y) is d(x,y) = ax + by + c
17//
18// Note that the distances below are not necessarily normalized. To get the true
19// distance, it's necessary to either call normalize() after xxxEndPoints(), or
20// divide the result of xxxDistance() by sqrt(normalSquared())
21
caryclark@google.com639df892012-01-10 21:46:10 +000022class LineParameters {
23public:
24 void cubicEndPoints(const Cubic& pts) {
25 a = pts[0].y - pts[3].y;
26 b = pts[3].x - pts[0].x;
27 c = pts[0].x * pts[3].y - pts[3].x * pts[0].y;
28 }
rmistry@google.comd6176b02012-08-23 18:14:13 +000029
caryclark@google.com639df892012-01-10 21:46:10 +000030 void cubicEndPoints(const Cubic& pts, int s, int e) {
31 a = pts[s].y - pts[e].y;
32 b = pts[e].x - pts[s].x;
33 c = pts[s].x * pts[e].y - pts[e].x * pts[s].y;
34 }
rmistry@google.comd6176b02012-08-23 18:14:13 +000035
caryclark@google.com639df892012-01-10 21:46:10 +000036 void lineEndPoints(const _Line& pts) {
37 a = pts[0].y - pts[1].y;
38 b = pts[1].x - pts[0].x;
39 c = pts[0].x * pts[1].y - pts[1].x * pts[0].y;
40 }
rmistry@google.comd6176b02012-08-23 18:14:13 +000041
caryclark@google.com639df892012-01-10 21:46:10 +000042 void quadEndPoints(const Quadratic& pts) {
43 a = pts[0].y - pts[2].y;
44 b = pts[2].x - pts[0].x;
45 c = pts[0].x * pts[2].y - pts[2].x * pts[0].y;
46 }
47
48 void quadEndPoints(const Quadratic& pts, int s, int e) {
49 a = pts[s].y - pts[e].y;
50 b = pts[e].x - pts[s].x;
51 c = pts[s].x * pts[e].y - pts[e].x * pts[s].y;
52 }
53
54 double normalSquared() {
55 return a * a + b * b;
56 }
57
58 bool normalize() {
59 double normal = sqrt(normalSquared());
caryclark@google.comb45a1b42012-05-18 20:50:33 +000060 if (approximately_zero_squared(normal)) {
caryclark@google.com639df892012-01-10 21:46:10 +000061 a = b = c = 0;
62 return false;
63 }
64 double reciprocal = 1 / normal;
65 a *= reciprocal;
66 b *= reciprocal;
67 c *= reciprocal;
68 return true;
69 }
rmistry@google.comd6176b02012-08-23 18:14:13 +000070
caryclark@google.com639df892012-01-10 21:46:10 +000071 void cubicDistanceY(const Cubic& pts, Cubic& distance) {
72 double oneThird = 1 / 3.0;
73 for (int index = 0; index < 4; ++index) {
74 distance[index].x = index * oneThird;
75 distance[index].y = a * pts[index].x + b * pts[index].y + c;
76 }
77 }
78
79 void quadDistanceY(const Quadratic& pts, Quadratic& distance) {
80 double oneHalf = 1 / 2.0;
81 for (int index = 0; index < 3; ++index) {
82 distance[index].x = index * oneHalf;
83 distance[index].y = a * pts[index].x + b * pts[index].y + c;
84 }
85 }
86
87 void controlPtDistance(const Cubic& pts, double distance[2]) {
88 for (int index = 0; index < 2; ++index) {
89 distance[index] = a * pts[index + 1].x + b * pts[index + 1].y + c;
90 }
91 }
rmistry@google.comd6176b02012-08-23 18:14:13 +000092
caryclark@google.com639df892012-01-10 21:46:10 +000093 void controlPtDistance(const Cubic& pts, int i, int j, double distance[2]) {
94 distance[0] = a * pts[i].x + b * pts[i].y + c;
95 distance[1] = a * pts[j].x + b * pts[j].y + c;
96 }
rmistry@google.comd6176b02012-08-23 18:14:13 +000097
caryclark@google.com639df892012-01-10 21:46:10 +000098 double controlPtDistance(const Quadratic& pts) {
99 return a * pts[1].x + b * pts[1].y + c;
100 }
rmistry@google.comd6176b02012-08-23 18:14:13 +0000101
caryclark@google.com639df892012-01-10 21:46:10 +0000102 double pointDistance(const _Point& pt) {
103 return a * pt.x + b * pt.y + c;
104 }
caryclark@google.comb45a1b42012-05-18 20:50:33 +0000105
caryclark@google.com639df892012-01-10 21:46:10 +0000106private:
107 double a;
108 double b;
109 double c;
110};