• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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  */
7 #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 
13 // 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 
22 class LineParameters {
23 public:
cubicEndPoints(const Cubic & pts)24     void cubicEndPoints(const Cubic& pts) {
25         cubicEndPoints(pts, 0, 3);
26     }
27 
cubicEndPoints(const Cubic & pts,int s,int e)28     void cubicEndPoints(const Cubic& pts, int s, int e) {
29         a = approximately_pin(pts[s].y - pts[e].y);
30         b = approximately_pin(pts[e].x - pts[s].x);
31         c = pts[s].x * pts[e].y - pts[e].x * pts[s].y;
32     }
33 
lineEndPoints(const _Line & pts)34     void lineEndPoints(const _Line& pts) {
35         a = approximately_pin(pts[0].y - pts[1].y);
36         b = approximately_pin(pts[1].x - pts[0].x);
37         c = pts[0].x * pts[1].y - pts[1].x * pts[0].y;
38     }
39 
quadEndPoints(const Quadratic & pts)40     void quadEndPoints(const Quadratic& pts) {
41         quadEndPoints(pts, 0, 2);
42     }
43 
quadEndPoints(const Quadratic & pts,int s,int e)44     void quadEndPoints(const Quadratic& pts, int s, int e) {
45         a = approximately_pin(pts[s].y - pts[e].y);
46         b = approximately_pin(pts[e].x - pts[s].x);
47         c = pts[s].x * pts[e].y - pts[e].x * pts[s].y;
48     }
49 
normalSquared()50     double normalSquared() const {
51         return a * a + b * b;
52     }
53 
normalize()54     bool normalize() {
55         double normal = sqrt(normalSquared());
56         if (approximately_zero(normal)) {
57             a = b = c = 0;
58             return false;
59         }
60         double reciprocal = 1 / normal;
61         a *= reciprocal;
62         b *= reciprocal;
63         c *= reciprocal;
64         return true;
65     }
66 
cubicDistanceY(const Cubic & pts,Cubic & distance)67     void cubicDistanceY(const Cubic& pts, Cubic& distance) const {
68         double oneThird = 1 / 3.0;
69         for (int index = 0; index < 4; ++index) {
70             distance[index].x = index * oneThird;
71             distance[index].y = a * pts[index].x + b * pts[index].y + c;
72         }
73     }
74 
quadDistanceY(const Quadratic & pts,Quadratic & distance)75     void quadDistanceY(const Quadratic& pts, Quadratic& distance) const {
76         double oneHalf = 1 / 2.0;
77         for (int index = 0; index < 3; ++index) {
78             distance[index].x = index * oneHalf;
79             distance[index].y = a * pts[index].x + b * pts[index].y + c;
80         }
81     }
82 
controlPtDistance(const Cubic & pts,int index)83     double controlPtDistance(const Cubic& pts, int index) const {
84         SkASSERT(index == 1 || index == 2);
85         return a * pts[index].x + b * pts[index].y + c;
86     }
87 
controlPtDistance(const Quadratic & pts)88     double controlPtDistance(const Quadratic& pts) const {
89         return a * pts[1].x + b * pts[1].y + c;
90     }
91 
pointDistance(const _Point & pt)92     double pointDistance(const _Point& pt) const {
93         return a * pt.x + b * pt.y + c;
94     }
95 
dx()96     double dx() const {
97         return b;
98     }
99 
dy()100     double dy() const {
101         return -a;
102     }
103 
104 private:
105     double a;
106     double b;
107     double c;
108 };
109