1 /* 2 * Copyright 2015 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 8 #ifndef SkPoint3_DEFINED 9 #define SkPoint3_DEFINED 10 11 #include "SkPoint.h" 12 13 struct SK_API SkPoint3 { 14 SkScalar fX, fY, fZ; 15 MakeSkPoint316 static SkPoint3 Make(SkScalar x, SkScalar y, SkScalar z) { 17 SkPoint3 pt; 18 pt.set(x, y, z); 19 return pt; 20 } 21 xSkPoint322 SkScalar x() const { return fX; } ySkPoint323 SkScalar y() const { return fY; } zSkPoint324 SkScalar z() const { return fZ; } 25 setSkPoint326 void set(SkScalar x, SkScalar y, SkScalar z) { fX = x; fY = y; fZ = z; } 27 28 friend bool operator==(const SkPoint3& a, const SkPoint3& b) { 29 return a.fX == b.fX && a.fY == b.fY && a.fZ == b.fZ; 30 } 31 32 friend bool operator!=(const SkPoint3& a, const SkPoint3& b) { 33 return !(a == b); 34 } 35 36 /** Returns the Euclidian distance from (0,0,0) to (x,y,z) 37 */ 38 static SkScalar Length(SkScalar x, SkScalar y, SkScalar z); 39 40 /** Return the Euclidian distance from (0,0,0) to the point 41 */ lengthSkPoint342 SkScalar length() const { return SkPoint3::Length(fX, fY, fZ); } 43 44 /** Set the point (vector) to be unit-length in the same direction as it 45 already points. If the point has a degenerate length (i.e., nearly 0) 46 then set it to (0,0,0) and return false; otherwise return true. 47 */ 48 bool normalize(); 49 50 /** Return a new point whose X, Y and Z coordinates are scaled. 51 */ makeScaleSkPoint352 SkPoint3 makeScale(SkScalar scale) const { 53 SkPoint3 p; 54 p.set(scale * fX, scale * fY, scale * fZ); 55 return p; 56 } 57 58 /** Scale the point's coordinates by scale. 59 */ scaleSkPoint360 void scale(SkScalar value) { 61 fX *= value; 62 fY *= value; 63 fZ *= value; 64 } 65 66 /** Return a new point whose X, Y and Z coordinates are the negative of the 67 original point's 68 */ 69 SkPoint3 operator-() const { 70 SkPoint3 neg; 71 neg.fX = -fX; 72 neg.fY = -fY; 73 neg.fZ = -fZ; 74 return neg; 75 } 76 77 /** Returns a new point whose coordinates are the difference between 78 a and b (i.e., a - b) 79 */ 80 friend SkPoint3 operator-(const SkPoint3& a, const SkPoint3& b) { 81 SkPoint3 v; 82 v.set(a.fX - b.fX, a.fY - b.fY, a.fZ - b.fZ); 83 return v; 84 } 85 86 /** Returns a new point whose coordinates are the sum of a and b (a + b) 87 */ 88 friend SkPoint3 operator+(const SkPoint3& a, const SkPoint3& b) { 89 SkPoint3 v; 90 v.set(a.fX + b.fX, a.fY + b.fY, a.fZ + b.fZ); 91 return v; 92 } 93 94 /** Add v's coordinates to the point's 95 */ 96 void operator+=(const SkPoint3& v) { 97 fX += v.fX; 98 fY += v.fY; 99 fZ += v.fZ; 100 } 101 102 /** Subtract v's coordinates from the point's 103 */ 104 void operator-=(const SkPoint3& v) { 105 fX -= v.fX; 106 fY -= v.fY; 107 fZ -= v.fZ; 108 } 109 110 /** Returns true if fX, fY, and fZ are measurable values. 111 112 @return true for values other than infinities and NaN 113 */ isFiniteSkPoint3114 bool isFinite() const { 115 SkScalar accum = 0; 116 accum *= fX; 117 accum *= fY; 118 accum *= fZ; 119 120 // accum is either NaN or it is finite (zero). 121 SkASSERT(0 == accum || SkScalarIsNaN(accum)); 122 123 // value==value will be true iff value is not NaN 124 // TODO: is it faster to say !accum or accum==accum? 125 return !SkScalarIsNaN(accum); 126 } 127 128 /** Returns the dot product of a and b, treating them as 3D vectors 129 */ DotProductSkPoint3130 static SkScalar DotProduct(const SkPoint3& a, const SkPoint3& b) { 131 return a.fX * b.fX + a.fY * b.fY + a.fZ * b.fZ; 132 } 133 dotSkPoint3134 SkScalar dot(const SkPoint3& vec) const { 135 return DotProduct(*this, vec); 136 } 137 }; 138 139 typedef SkPoint3 SkVector3; 140 typedef SkPoint3 SkColor3f; 141 142 #endif 143