blob: f038afb4430ea31eef97e61c84b3945a99a13d51 [file] [log] [blame]
reed@android.com8a1c16f2008-12-17 15:59:43 +00001/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef SkPoint_DEFINED
18#define SkPoint_DEFINED
19
20#include "SkMath.h"
21#include "SkScalar.h"
22
23/** \struct SkIPoint
24
25 SkIPoint holds two 32 bit integer coordinates
26*/
27struct SkIPoint {
28 int32_t fX, fY;
29
30 /** Set the x and y values of the point. */
31 void set(int32_t x, int32_t y) { fX = x; fY = y; }
32
33 /** Rotate the point clockwise, writing the new point into dst
34 It is legal for dst == this
35 */
36 void rotateCW(SkIPoint* dst) const;
37
38 /** Rotate the point clockwise, writing the new point back into the point
39 */
40
41 void rotateCW() { this->rotateCW(this); }
42
43 /** Rotate the point counter-clockwise, writing the new point into dst.
44 It is legal for dst == this
45 */
46 void rotateCCW(SkIPoint* dst) const;
47
48 /** Rotate the point counter-clockwise, writing the new point back into
49 the point
50 */
51 void rotateCCW() { this->rotateCCW(this); }
52
53 /** Negate the X and Y coordinates of the point.
54 */
55 void negate() { fX = -fX; fY = -fY; }
56
57 /** Return a new point whose X and Y coordinates are the negative of the
58 original point's
59 */
60 SkIPoint operator-() const {
61 SkIPoint neg;
62 neg.fX = -fX;
63 neg.fY = -fY;
64 return neg;
65 }
66
67 /** Add v's coordinates to this point's */
68 void operator+=(const SkIPoint& v) {
69 fX += v.fX;
70 fY += v.fY;
71 }
72
73 /** Subtract v's coordinates from this point's */
74 void operator-=(const SkIPoint& v) {
75 fX -= v.fX;
76 fY -= v.fY;
77 }
78
79 /** Returns true if the point's coordinates equal (x,y) */
80 bool equals(int32_t x, int32_t y) const {
81 return fX == x && fY == y;
82 }
83
84 friend bool operator==(const SkIPoint& a, const SkIPoint& b) {
85 return a.fX == b.fX && a.fY == b.fY;
86 }
87
88 friend bool operator!=(const SkIPoint& a, const SkIPoint& b) {
89 return a.fX != b.fX || a.fY != b.fY;
90 }
91
92 /** Returns a new point whose coordinates are the difference between
93 a and b (i.e. a - b)
94 */
95 friend SkIPoint operator-(const SkIPoint& a, const SkIPoint& b) {
96 SkIPoint v;
97 v.set(a.fX - b.fX, a.fY - b.fY);
98 return v;
99 }
100
101 /** Returns a new point whose coordinates are the sum of a and b (a + b)
102 */
103 friend SkIPoint operator+(const SkIPoint& a, const SkIPoint& b) {
104 SkIPoint v;
105 v.set(a.fX + b.fX, a.fY + b.fY);
106 return v;
107 }
108
109 /** Returns the dot product of a and b, treating them as 2D vectors
110 */
111 static int32_t DotProduct(const SkIPoint& a, const SkIPoint& b) {
112 return a.fX * b.fX + a.fY * b.fY;
113 }
114
115 /** Returns the cross product of a and b, treating them as 2D vectors
116 */
117 static int32_t CrossProduct(const SkIPoint& a, const SkIPoint& b) {
118 return a.fX * b.fY - a.fY * b.fX;
119 }
120};
121
122struct SkPoint {
123 SkScalar fX, fY;
124
125 /** Set the point's X and Y coordinates */
126 void set(SkScalar x, SkScalar y) { fX = x; fY = y; }
127
128 /** Set the point's X and Y coordinates by automatically promoting (x,y) to
129 SkScalar values.
130 */
131 void iset(int32_t x, int32_t y) {
132 fX = SkIntToScalar(x);
133 fY = SkIntToScalar(y);
134 }
135
136 /** Set the point's X and Y coordinates by automatically promoting p's
137 coordinates to SkScalar values.
138 */
139 void iset(const SkIPoint& p) {
140 fX = SkIntToScalar(p.fX);
141 fY = SkIntToScalar(p.fY);
142 }
143
144 /** Return the euclidian distance from (0,0) to the point
145 */
146 SkScalar length() const { return SkPoint::Length(fX, fY); }
147
148 /** Set the point (vector) to be unit-length in the same direction as it
149 currently is, and return its old length. If the old length is
150 degenerately small (nearly zero), do nothing and return false, otherwise
151 return true.
152 */
153 bool normalize();
154
155 /** Set the point (vector) to be unit-length in the same direction as the
156 x,y params. If the vector (x,y) has a degenerate length (i.e. nearly 0)
157 then return false and do nothing, otherwise return true.
158 */
159 bool setNormalize(SkScalar x, SkScalar y);
160
161 /** Scale the point (vector) to have the specified length, and return that
162 length. If the original length is degenerately small (nearly zero),
163 do nothing and return false, otherwise return true.
164 */
165 bool setLength(SkScalar length);
166
167 /** Set the point (vector) to have the specified length in the same
168 direction as (x,y). If the vector (x,y) has a degenerate length
169 (i.e. nearly 0) then return false and do nothing, otherwise return true.
170 */
171 bool setLength(SkScalar x, SkScalar y, SkScalar length);
172
173 /** Scale the point's coordinates by scale, writing the answer into dst.
174 It is legal for dst == this.
175 */
176 void scale(SkScalar scale, SkPoint* dst) const;
177
178 /** Scale the point's coordinates by scale, writing the answer back into
179 the point.
180 */
181 void scale(SkScalar scale) { this->scale(scale, this); }
182
183 /** Rotate the point clockwise by 90 degrees, writing the answer into dst.
184 It is legal for dst == this.
185 */
186 void rotateCW(SkPoint* dst) const;
187
188 /** Rotate the point clockwise by 90 degrees, writing the answer back into
189 the point.
190 */
191 void rotateCW() { this->rotateCW(this); }
192
193 /** Rotate the point counter-clockwise by 90 degrees, writing the answer
194 into dst. It is legal for dst == this.
195 */
196 void rotateCCW(SkPoint* dst) const;
197
198 /** Rotate the point counter-clockwise by 90 degrees, writing the answer
199 back into the point.
200 */
201 void rotateCCW() { this->rotateCCW(this); }
202
203 /** Negate the point's coordinates
204 */
205 void negate() {
206 fX = -fX;
207 fY = -fY;
208 }
209
210 /** Returns a new point whose coordinates are the negative of the point's
211 */
212 SkPoint operator-() const {
213 SkPoint neg;
214 neg.fX = -fX;
215 neg.fY = -fY;
216 return neg;
217 }
218
219 /** Add v's coordinates to the point's
220 */
221 void operator+=(const SkPoint& v) {
222 fX += v.fX;
223 fY += v.fY;
224 }
225
226 /** Subtract v's coordinates from the point's
227 */
228 void operator-=(const SkPoint& v) {
229 fX -= v.fX;
230 fY -= v.fY;
231 }
232
233 /** Returns true if the point's coordinates equal (x,y)
234 */
235 bool equals(SkScalar x, SkScalar y) const { return fX == x && fY == y; }
236
237 friend bool operator==(const SkPoint& a, const SkPoint& b) {
238 return a.fX == b.fX && a.fY == b.fY;
239 }
240
241 friend bool operator!=(const SkPoint& a, const SkPoint& b) {
242 return a.fX != b.fX || a.fY != b.fY;
243 }
244
245 /** Returns a new point whose coordinates are the difference between
246 a's and b's (a - b)
247 */
248 friend SkPoint operator-(const SkPoint& a, const SkPoint& b) {
249 SkPoint v;
250 v.set(a.fX - b.fX, a.fY - b.fY);
251 return v;
252 }
253
254 /** Returns a new point whose coordinates are the sum of a's and b's (a + b)
255 */
256 friend SkPoint operator+(const SkPoint& a, const SkPoint& b) {
257 SkPoint v;
258 v.set(a.fX + b.fX, a.fY + b.fY);
259 return v;
260 }
261
262 /** Returns the euclidian distance from (0,0) to (x,y)
263 */
264 static SkScalar Length(SkScalar x, SkScalar y);
265
266 /** Returns the euclidian distance between a and b
267 */
268 static SkScalar Distance(const SkPoint& a, const SkPoint& b) {
269 return Length(a.fX - b.fX, a.fY - b.fY);
270 }
271
272 /** Returns the dot product of a and b, treating them as 2D vectors
273 */
274 static SkScalar DotProduct(const SkPoint& a, const SkPoint& b) {
275 return SkScalarMul(a.fX, b.fX) + SkScalarMul(a.fY, b.fY);
276 }
277
278 /** Returns the cross product of a and b, treating them as 2D vectors
279 */
280 static SkScalar CrossProduct(const SkPoint& a, const SkPoint& b) {
281 return SkScalarMul(a.fX, b.fY) - SkScalarMul(a.fY, b.fX);
282 }
283};
284
285typedef SkPoint SkVector;
286
287#endif
288