blob: 534154f199ccd2994026e6d286600e96cdbfc97b [file] [log] [blame]
caryclark@google.com07393ca2013-04-08 11:47:37 +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 */
7#ifndef SkPathOpsPoint_DEFINED
8#define SkPathOpsPoint_DEFINED
9
10#include "SkPathOpsTypes.h"
11#include "SkPoint.h"
12
caryclark@google.coma5e55922013-05-07 18:51:31 +000013inline bool AlmostEqualUlps(const SkPoint& pt1, const SkPoint& pt2) {
14 return AlmostEqualUlps(pt1.fX, pt2.fX) && AlmostEqualUlps(pt1.fY, pt2.fY);
15}
16
caryclark@google.com07393ca2013-04-08 11:47:37 +000017struct SkDVector {
18 double fX, fY;
19
20 friend SkDPoint operator+(const SkDPoint& a, const SkDVector& b);
21
22 void operator+=(const SkDVector& v) {
23 fX += v.fX;
24 fY += v.fY;
25 }
26
27 void operator-=(const SkDVector& v) {
28 fX -= v.fX;
29 fY -= v.fY;
30 }
31
32 void operator/=(const double s) {
33 fX /= s;
34 fY /= s;
35 }
36
37 void operator*=(const double s) {
38 fX *= s;
39 fY *= s;
40 }
41
42 SkVector asSkVector() const {
43 SkVector v = {SkDoubleToScalar(fX), SkDoubleToScalar(fY)};
44 return v;
45 }
46
47 double cross(const SkDVector& a) const {
48 return fX * a.fY - fY * a.fX;
49 }
50
51 double dot(const SkDVector& a) const {
52 return fX * a.fX + fY * a.fY;
53 }
54
55 double length() const {
56 return sqrt(lengthSquared());
57 }
58
59 double lengthSquared() const {
60 return fX * fX + fY * fY;
61 }
62};
63
64struct SkDPoint {
65 double fX;
66 double fY;
67
68 void set(const SkPoint& pt) {
69 fX = pt.fX;
70 fY = pt.fY;
71 }
72
73 friend SkDVector operator-(const SkDPoint& a, const SkDPoint& b);
74
75 friend bool operator==(const SkDPoint& a, const SkDPoint& b) {
76 return a.fX == b.fX && a.fY == b.fY;
77 }
78
79 friend bool operator!=(const SkDPoint& a, const SkDPoint& b) {
80 return a.fX != b.fX || a.fY != b.fY;
81 }
82
83 void operator=(const SkPoint& pt) {
84 fX = pt.fX;
85 fY = pt.fY;
86 }
87
88
89 void operator+=(const SkDVector& v) {
90 fX += v.fX;
91 fY += v.fY;
92 }
93
94 void operator-=(const SkDVector& v) {
95 fX -= v.fX;
96 fY -= v.fY;
97 }
98
99 // note: this can not be implemented with
100 // return approximately_equal(a.fY, fY) && approximately_equal(a.fX, fX);
101 // because that will not take the magnitude of the values
102 bool approximatelyEqual(const SkDPoint& a) const {
caryclark@google.com3b97af52013-04-23 11:56:44 +0000103 double denom = SkTMax(fabs(fX), SkTMax(fabs(fY),
104 SkTMax(fabs(a.fX), fabs(a.fY))));
caryclark@google.com07393ca2013-04-08 11:47:37 +0000105 if (denom == 0) {
106 return true;
107 }
108 double inv = 1 / denom;
109 return approximately_equal(fX * inv, a.fX * inv)
110 && approximately_equal(fY * inv, a.fY * inv);
111 }
112
113 bool approximatelyEqual(const SkPoint& a) const {
caryclark@google.com3b97af52013-04-23 11:56:44 +0000114 double denom = SkTMax(fabs(fX), SkTMax(fabs(fY),
115 SkScalarToDouble(SkTMax(fabsf(a.fX), fabsf(a.fY)))));
caryclark@google.com07393ca2013-04-08 11:47:37 +0000116 if (denom == 0) {
117 return true;
118 }
119 double inv = 1 / denom;
caryclark@google.comcffbcc32013-06-04 17:59:42 +0000120 return approximately_equal_double(fX * inv, a.fX * inv)
121 && approximately_equal_double(fY * inv, a.fY * inv);
caryclark@google.com07393ca2013-04-08 11:47:37 +0000122 }
123
124 bool approximatelyEqualHalf(const SkDPoint& a) const {
caryclark@google.com3b97af52013-04-23 11:56:44 +0000125 double denom = SkTMax(fabs(fX), SkTMax(fabs(fY),
126 SkTMax(fabs(a.fX), fabs(a.fY))));
caryclark@google.com07393ca2013-04-08 11:47:37 +0000127 if (denom == 0) {
128 return true;
129 }
130 double inv = 1 / denom;
131 return approximately_equal_half(fX * inv, a.fX * inv)
132 && approximately_equal_half(fY * inv, a.fY * inv);
133 }
134
135 bool approximatelyZero() const {
136 return approximately_zero(fX) && approximately_zero(fY);
137 }
138
139 SkPoint asSkPoint() const {
140 SkPoint pt = {SkDoubleToScalar(fX), SkDoubleToScalar(fY)};
141 return pt;
142 }
143
144 double distance(const SkDPoint& a) const {
145 SkDVector temp = *this - a;
146 return temp.length();
147 }
148
149 double distanceSquared(const SkDPoint& a) const {
150 SkDVector temp = *this - a;
151 return temp.lengthSquared();
152 }
153
caryclark@google.comcffbcc32013-06-04 17:59:42 +0000154 static SkDPoint Mid(const SkDPoint& a, const SkDPoint& b) {
155 SkDPoint result;
156 result.fX = (a.fX + b.fX) / 2;
157 result.fY = (a.fY + b.fY) / 2;
158 return result;
159 }
160
caryclark@google.com07393ca2013-04-08 11:47:37 +0000161 double moreRoughlyEqual(const SkDPoint& a) const {
162 return more_roughly_equal(a.fY, fY) && more_roughly_equal(a.fX, fX);
163 }
164
165 double roughlyEqual(const SkDPoint& a) const {
166 return roughly_equal(a.fY, fY) && roughly_equal(a.fX, fX);
167 }
168};
169
170#endif