Skia
2DGraphicsLibrary
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
SkPoint.h
1 /*
2  * Copyright 2006 The Android Open Source Project
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 
8 #ifndef SkPoint_DEFINED
9 #define SkPoint_DEFINED
10 
11 #include "SkMath.h"
12 #include "SkScalar.h"
13 
18 struct SkIPoint16 {
19  int16_t fX, fY;
20 
21  static SkIPoint16 Make(int x, int y) {
22  SkIPoint16 pt;
23  pt.set(x, y);
24  return pt;
25  }
26 
27  int16_t x() const { return fX; }
28  int16_t y() const { return fY; }
29 
30  void set(int x, int y) {
31  fX = SkToS16(x);
32  fY = SkToS16(y);
33  }
34 };
35 
40 struct SkIPoint {
41  int32_t fX, fY;
42 
43  static SkIPoint Make(int32_t x, int32_t y) {
44  SkIPoint pt;
45  pt.set(x, y);
46  return pt;
47  }
48 
49  int32_t x() const { return fX; }
50  int32_t y() const { return fY; }
51  void setX(int32_t x) { fX = x; }
52  void setY(int32_t y) { fY = y; }
53 
57  bool isZero() const { return (fX | fY) == 0; }
58 
62  void setZero() { fX = fY = 0; }
63 
65  void set(int32_t x, int32_t y) { fX = x; fY = y; }
66 
70  void rotateCW(SkIPoint* dst) const;
71 
75  void rotateCW() { this->rotateCW(this); }
76 
80  void rotateCCW(SkIPoint* dst) const;
81 
85  void rotateCCW() { this->rotateCCW(this); }
86 
89  void negate() { fX = -fX; fY = -fY; }
90 
94  SkIPoint operator-() const {
95  SkIPoint neg;
96  neg.fX = -fX;
97  neg.fY = -fY;
98  return neg;
99  }
100 
102  void operator+=(const SkIPoint& v) {
103  fX += v.fX;
104  fY += v.fY;
105  }
106 
108  void operator-=(const SkIPoint& v) {
109  fX -= v.fX;
110  fY -= v.fY;
111  }
112 
114  bool equals(int32_t x, int32_t y) const {
115  return fX == x && fY == y;
116  }
117 
118  friend bool operator==(const SkIPoint& a, const SkIPoint& b) {
119  return a.fX == b.fX && a.fY == b.fY;
120  }
121 
122  friend bool operator!=(const SkIPoint& a, const SkIPoint& b) {
123  return a.fX != b.fX || a.fY != b.fY;
124  }
125 
129  friend SkIPoint operator-(const SkIPoint& a, const SkIPoint& b) {
130  SkIPoint v;
131  v.set(a.fX - b.fX, a.fY - b.fY);
132  return v;
133  }
134 
137  friend SkIPoint operator+(const SkIPoint& a, const SkIPoint& b) {
138  SkIPoint v;
139  v.set(a.fX + b.fX, a.fY + b.fY);
140  return v;
141  }
142 
145  static int32_t DotProduct(const SkIPoint& a, const SkIPoint& b) {
146  return a.fX * b.fX + a.fY * b.fY;
147  }
148 
151  static int32_t CrossProduct(const SkIPoint& a, const SkIPoint& b) {
152  return a.fX * b.fY - a.fY * b.fX;
153  }
154 };
155 
156 struct SK_API SkPoint {
157  SkScalar fX, fY;
158 
159  static SkPoint Make(SkScalar x, SkScalar y) {
160  SkPoint pt;
161  pt.set(x, y);
162  return pt;
163  }
164 
165  SkScalar x() const { return fX; }
166  SkScalar y() const { return fY; }
167 
171  bool isZero() const { return (0 == fX) & (0 == fY); }
172 
174  void set(SkScalar x, SkScalar y) { fX = x; fY = y; }
175 
179  void iset(int32_t x, int32_t y) {
180  fX = SkIntToScalar(x);
181  fY = SkIntToScalar(y);
182  }
183 
187  void iset(const SkIPoint& p) {
188  fX = SkIntToScalar(p.fX);
189  fY = SkIntToScalar(p.fY);
190  }
191 
192  void setAbs(const SkPoint& pt) {
193  fX = SkScalarAbs(pt.fX);
194  fY = SkScalarAbs(pt.fY);
195  }
196 
197  // counter-clockwise fan
198  void setIRectFan(int l, int t, int r, int b) {
199  SkPoint* v = this;
200  v[0].set(SkIntToScalar(l), SkIntToScalar(t));
201  v[1].set(SkIntToScalar(l), SkIntToScalar(b));
202  v[2].set(SkIntToScalar(r), SkIntToScalar(b));
203  v[3].set(SkIntToScalar(r), SkIntToScalar(t));
204  }
205  void setIRectFan(int l, int t, int r, int b, size_t stride);
206 
207  // counter-clockwise fan
208  void setRectFan(SkScalar l, SkScalar t, SkScalar r, SkScalar b) {
209  SkPoint* v = this;
210  v[0].set(l, t);
211  v[1].set(l, b);
212  v[2].set(r, b);
213  v[3].set(r, t);
214  }
215 
216  void setRectFan(SkScalar l, SkScalar t, SkScalar r, SkScalar b, size_t stride) {
217  SkASSERT(stride >= sizeof(SkPoint));
218 
219  ((SkPoint*)((intptr_t)this + 0 * stride))->set(l, t);
220  ((SkPoint*)((intptr_t)this + 1 * stride))->set(l, b);
221  ((SkPoint*)((intptr_t)this + 2 * stride))->set(r, b);
222  ((SkPoint*)((intptr_t)this + 3 * stride))->set(r, t);
223  }
224 
225 
226  static void Offset(SkPoint points[], int count, const SkPoint& offset) {
227  Offset(points, count, offset.fX, offset.fY);
228  }
229 
230  static void Offset(SkPoint points[], int count, SkScalar dx, SkScalar dy) {
231  for (int i = 0; i < count; ++i) {
232  points[i].offset(dx, dy);
233  }
234  }
235 
236  void offset(SkScalar dx, SkScalar dy) {
237  fX += dx;
238  fY += dy;
239  }
240 
243  SkScalar length() const { return SkPoint::Length(fX, fY); }
244  SkScalar distanceToOrigin() const { return this->length(); }
245 
250  static bool CanNormalize(SkScalar dx, SkScalar dy) {
251  // Simple enough (and performance critical sometimes) so we inline it.
252  return (dx*dx + dy*dy) > (SK_ScalarNearlyZero * SK_ScalarNearlyZero);
253  }
254 
255  bool canNormalize() const {
256  return CanNormalize(fX, fY);
257  }
258 
263  bool normalize();
264 
269  bool setNormalize(SkScalar x, SkScalar y);
270 
275  bool setLength(SkScalar length);
276 
281  bool setLength(SkScalar x, SkScalar y, SkScalar length);
282 
285  bool setLengthFast(SkScalar length);
286 
289  bool setLengthFast(SkScalar x, SkScalar y, SkScalar length);
290 
294  void scale(SkScalar scale, SkPoint* dst) const;
295 
299  void scale(SkScalar value) { this->scale(value, this); }
300 
304  void rotateCW(SkPoint* dst) const;
305 
309  void rotateCW() { this->rotateCW(this); }
310 
314  void rotateCCW(SkPoint* dst) const;
315 
319  void rotateCCW() { this->rotateCCW(this); }
320 
323  void negate() {
324  fX = -fX;
325  fY = -fY;
326  }
327 
330  SkPoint operator-() const {
331  SkPoint neg;
332  neg.fX = -fX;
333  neg.fY = -fY;
334  return neg;
335  }
336 
339  void operator+=(const SkPoint& v) {
340  fX += v.fX;
341  fY += v.fY;
342  }
343 
346  void operator-=(const SkPoint& v) {
347  fX -= v.fX;
348  fY -= v.fY;
349  }
350 
351  SkPoint operator*(SkScalar scale) const {
352  return Make(fX * scale, fY * scale);
353  }
354 
355  SkPoint& operator*=(SkScalar scale) {
356  fX *= scale;
357  fY *= scale;
358  return *this;
359  }
360 
364  bool isFinite() const {
365  SkScalar accum = 0;
366  accum *= fX;
367  accum *= fY;
368 
369  // accum is either NaN or it is finite (zero).
370  SkASSERT(0 == accum || SkScalarIsNaN(accum));
371 
372  // value==value will be true iff value is not NaN
373  // TODO: is it faster to say !accum or accum==accum?
374  return !SkScalarIsNaN(accum);
375  }
376 
380  bool equals(SkScalar x, SkScalar y) const {
381  return fX == x && fY == y;
382  }
383 
384  friend bool operator==(const SkPoint& a, const SkPoint& b) {
385  return a.fX == b.fX && a.fY == b.fY;
386  }
387 
388  friend bool operator!=(const SkPoint& a, const SkPoint& b) {
389  return a.fX != b.fX || a.fY != b.fY;
390  }
391 
401  bool equalsWithinTolerance(const SkPoint& p) const {
402  return !CanNormalize(fX - p.fX, fY - p.fY);
403  }
404 
409  bool equalsWithinTolerance(const SkPoint& p, SkScalar tol) const {
410  return SkScalarNearlyZero(fX - p.fX, tol)
411  && SkScalarNearlyZero(fY - p.fY, tol);
412  }
413 
417  friend SkPoint operator-(const SkPoint& a, const SkPoint& b) {
418  SkPoint v;
419  v.set(a.fX - b.fX, a.fY - b.fY);
420  return v;
421  }
422 
425  friend SkPoint operator+(const SkPoint& a, const SkPoint& b) {
426  SkPoint v;
427  v.set(a.fX + b.fX, a.fY + b.fY);
428  return v;
429  }
430 
433  static SkScalar Length(SkScalar x, SkScalar y);
434 
444  static SkScalar Normalize(SkPoint* pt);
445 
448  static SkScalar Distance(const SkPoint& a, const SkPoint& b) {
449  return Length(a.fX - b.fX, a.fY - b.fY);
450  }
451 
454  static SkScalar DotProduct(const SkPoint& a, const SkPoint& b) {
455  return a.fX * b.fX + a.fY * b.fY;
456  }
457 
460  static SkScalar CrossProduct(const SkPoint& a, const SkPoint& b) {
461  return a.fX * b.fY - a.fY * b.fX;
462  }
463 
464  SkScalar cross(const SkPoint& vec) const {
465  return CrossProduct(*this, vec);
466  }
467 
468  SkScalar dot(const SkPoint& vec) const {
469  return DotProduct(*this, vec);
470  }
471 
472  SkScalar lengthSqd() const {
473  return DotProduct(*this, *this);
474  }
475 
476  SkScalar distanceToSqd(const SkPoint& pt) const {
477  SkScalar dx = fX - pt.fX;
478  SkScalar dy = fY - pt.fY;
479  return dx * dx + dy * dy;
480  }
481 
486  enum Side {
487  kLeft_Side = -1,
488  kOn_Side = 0,
489  kRight_Side = 1
490  };
491 
497  SkScalar distanceToLineBetweenSqd(const SkPoint& a,
498  const SkPoint& b,
499  Side* side = NULL) const;
500 
506  SkScalar distanceToLineBetween(const SkPoint& a,
507  const SkPoint& b,
508  Side* side = NULL) const {
509  return SkScalarSqrt(this->distanceToLineBetweenSqd(a, b, side));
510  }
511 
515  SkScalar distanceToLineSegmentBetweenSqd(const SkPoint& a,
516  const SkPoint& b) const;
517 
522  const SkPoint& b) const {
523  return SkScalarSqrt(this->distanceToLineSegmentBetweenSqd(a, b));
524  }
525 
531  void setOrthog(const SkPoint& vec, Side side = kLeft_Side) {
532  // vec could be this
533  SkScalar tmp = vec.fX;
534  if (kRight_Side == side) {
535  fX = -vec.fY;
536  fY = tmp;
537  } else {
538  SkASSERT(kLeft_Side == side);
539  fX = vec.fY;
540  fY = -tmp;
541  }
542  }
543 
547  const SkScalar* asScalars() const { return &fX; }
548 };
549 
550 typedef SkPoint SkVector;
551 
552 static inline bool SkPointsAreFinite(const SkPoint array[], int count) {
553  return SkScalarsAreFinite(&array[0].fX, count << 1);
554 }
555 
556 #endif
void operator-=(const SkPoint &v)
Subtract v's coordinates from the point's.
Definition: SkPoint.h:346
SkScalar distanceToLineBetween(const SkPoint &a, const SkPoint &b, Side *side=NULL) const
Returns the distance to the infinite line between two pts.
Definition: SkPoint.h:506
static SkScalar Length(SkScalar x, SkScalar y)
Returns the euclidian distance from (0,0) to (x,y)
void iset(const SkIPoint &p)
Set the point's X and Y coordinates by automatically promoting p's coordinates to SkScalar values...
Definition: SkPoint.h:187
void set(SkScalar x, SkScalar y)
Set the point's X and Y coordinates.
Definition: SkPoint.h:174
void negate()
Negate the point's coordinates.
Definition: SkPoint.h:323
SkIPoint operator-() const
Return a new point whose X and Y coordinates are the negative of the original point's.
Definition: SkPoint.h:94
bool equalsWithinTolerance(const SkPoint &p, SkScalar tol) const
WARNING: There is no guarantee that the result will reflect judgments elsewhere regarding degeneracy ...
Definition: SkPoint.h:409
Definition: SkPoint.h:156
static SkScalar Distance(const SkPoint &a, const SkPoint &b)
Returns the euclidian distance between a and b.
Definition: SkPoint.h:448
const SkScalar * asScalars() const
cast-safe way to treat the point as an array of (2) SkScalars.
Definition: SkPoint.h:547
void operator+=(const SkIPoint &v)
Add v's coordinates to this point's.
Definition: SkPoint.h:102
friend SkIPoint operator+(const SkIPoint &a, const SkIPoint &b)
Returns a new point whose coordinates are the sum of a and b (a + b)
Definition: SkPoint.h:137
bool isFinite() const
Returns true if both X and Y are finite (not infinity or NaN)
Definition: SkPoint.h:364
SkScalar length() const
Return the euclidian distance from (0,0) to the point.
Definition: SkPoint.h:243
Side
The side of a point relative to a line.
Definition: SkPoint.h:486
void setZero()
Set both fX and fY to zero.
Definition: SkPoint.h:62
void rotateCCW()
Rotate the point counter-clockwise by 90 degrees, writing the answer back into the point...
Definition: SkPoint.h:319
static bool CanNormalize(SkScalar dx, SkScalar dy)
Return true if the computed length of the vector is >= the internal tolerance (used to avoid dividing...
Definition: SkPoint.h:250
void rotateCW()
Rotate the point clockwise, writing the new point back into the point.
Definition: SkPoint.h:75
static SkScalar DotProduct(const SkPoint &a, const SkPoint &b)
Returns the dot product of a and b, treating them as 2D vectors.
Definition: SkPoint.h:454
bool isZero() const
Returns true iff fX and fY are both zero.
Definition: SkPoint.h:57
SkIPoint holds two 16 bit integer coordinates.
Definition: SkPoint.h:18
bool equals(int32_t x, int32_t y) const
Returns true if the point's coordinates equal (x,y)
Definition: SkPoint.h:114
void setOrthog(const SkPoint &vec, Side side=kLeft_Side)
Make this vector be orthogonal to vec.
Definition: SkPoint.h:531
bool equals(SkScalar x, SkScalar y) const
Returns true if the point's coordinates equal (x,y)
Definition: SkPoint.h:380
static SkScalar CrossProduct(const SkPoint &a, const SkPoint &b)
Returns the cross product of a and b, treating them as 2D vectors.
Definition: SkPoint.h:460
SkScalar distanceToLineSegmentBetween(const SkPoint &a, const SkPoint &b) const
Returns the distance to the line segment between pts a and b.
Definition: SkPoint.h:521
static int32_t DotProduct(const SkIPoint &a, const SkIPoint &b)
Returns the dot product of a and b, treating them as 2D vectors.
Definition: SkPoint.h:145
void negate()
Negate the X and Y coordinates of the point.
Definition: SkPoint.h:89
SkPoint operator-() const
Returns a new point whose coordinates are the negative of the point's.
Definition: SkPoint.h:330
void iset(int32_t x, int32_t y)
Set the point's X and Y coordinates by automatically promoting (x,y) to SkScalar values.
Definition: SkPoint.h:179
friend SkPoint operator-(const SkPoint &a, const SkPoint &b)
Returns a new point whose coordinates are the difference between a's and b's (a - b) ...
Definition: SkPoint.h:417
friend SkPoint operator+(const SkPoint &a, const SkPoint &b)
Returns a new point whose coordinates are the sum of a's and b's (a + b)
Definition: SkPoint.h:425
void operator+=(const SkPoint &v)
Add v's coordinates to the point's.
Definition: SkPoint.h:339
void set(int32_t x, int32_t y)
Set the x and y values of the point.
Definition: SkPoint.h:65
friend SkIPoint operator-(const SkIPoint &a, const SkIPoint &b)
Returns a new point whose coordinates are the difference between a and b (i.e.
Definition: SkPoint.h:129
void rotateCCW()
Rotate the point counter-clockwise, writing the new point back into the point.
Definition: SkPoint.h:85
bool equalsWithinTolerance(const SkPoint &p) const
Return true if this point and the given point are far enough apart such that a vector between them wo...
Definition: SkPoint.h:401
void operator-=(const SkIPoint &v)
Subtract v's coordinates from this point's.
Definition: SkPoint.h:108
static int32_t CrossProduct(const SkIPoint &a, const SkIPoint &b)
Returns the cross product of a and b, treating them as 2D vectors.
Definition: SkPoint.h:151
SkIPoint holds two 32 bit integer coordinates.
Definition: SkPoint.h:40
bool isZero() const
Returns true iff fX and fY are both zero.
Definition: SkPoint.h:171
void scale(SkScalar value)
Scale the point's coordinates by scale, writing the answer back into the point.
Definition: SkPoint.h:299
void rotateCW()
Rotate the point clockwise by 90 degrees, writing the answer back into the point. ...
Definition: SkPoint.h:309