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 "include/core/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 22 /** Writes text representation of SkPoint3 to string. 23 24 @param desc the string storing a description of parameters. 25 @param depth the number of tabs preceding each line. 26 */ 27 void dump(std::string& desc, int depth) const; 28 xSkPoint329 SkScalar x() const { return fX; } ySkPoint330 SkScalar y() const { return fY; } zSkPoint331 SkScalar z() const { return fZ; } 32 setSkPoint333 void set(SkScalar x, SkScalar y, SkScalar z) { fX = x; fY = y; fZ = z; } 34 35 friend bool operator==(const SkPoint3& a, const SkPoint3& b) { 36 return a.fX == b.fX && a.fY == b.fY && a.fZ == b.fZ; 37 } 38 39 friend bool operator!=(const SkPoint3& a, const SkPoint3& b) { 40 return !(a == b); 41 } 42 43 /** Returns the Euclidian distance from (0,0,0) to (x,y,z) 44 */ 45 static SkScalar Length(SkScalar x, SkScalar y, SkScalar z); 46 47 /** Return the Euclidian distance from (0,0,0) to the point 48 */ lengthSkPoint349 SkScalar length() const { return SkPoint3::Length(fX, fY, fZ); } 50 51 /** Set the point (vector) to be unit-length in the same direction as it 52 already points. If the point has a degenerate length (i.e., nearly 0) 53 then set it to (0,0,0) and return false; otherwise return true. 54 */ 55 bool normalize(); 56 57 /** Return a new point whose X, Y and Z coordinates are scaled. 58 */ makeScaleSkPoint359 SkPoint3 makeScale(SkScalar scale) const { 60 SkPoint3 p; 61 p.set(scale * fX, scale * fY, scale * fZ); 62 return p; 63 } 64 65 /** Scale the point's coordinates by scale. 66 */ scaleSkPoint367 void scale(SkScalar value) { 68 fX *= value; 69 fY *= value; 70 fZ *= value; 71 } 72 73 /** Return a new point whose X, Y and Z coordinates are the negative of the 74 original point's 75 */ 76 SkPoint3 operator-() const { 77 SkPoint3 neg; 78 neg.fX = -fX; 79 neg.fY = -fY; 80 neg.fZ = -fZ; 81 return neg; 82 } 83 84 /** Returns a new point whose coordinates are the difference between 85 a and b (i.e., a - b) 86 */ 87 friend SkPoint3 operator-(const SkPoint3& a, const SkPoint3& b) { 88 return { a.fX - b.fX, a.fY - b.fY, a.fZ - b.fZ }; 89 } 90 91 /** Returns a new point whose coordinates are the sum of a and b (a + b) 92 */ 93 friend SkPoint3 operator+(const SkPoint3& a, const SkPoint3& b) { 94 return { a.fX + b.fX, a.fY + b.fY, a.fZ + b.fZ }; 95 } 96 97 /** Add v's coordinates to the point's 98 */ 99 void operator+=(const SkPoint3& v) { 100 fX += v.fX; 101 fY += v.fY; 102 fZ += v.fZ; 103 } 104 105 /** Subtract v's coordinates from the point's 106 */ 107 void operator-=(const SkPoint3& v) { 108 fX -= v.fX; 109 fY -= v.fY; 110 fZ -= v.fZ; 111 } 112 113 friend SkPoint3 operator*(SkScalar t, SkPoint3 p) { 114 return { t * p.fX, t * p.fY, t * p.fZ }; 115 } 116 117 /** Returns true if fX, fY, and fZ are measurable values. 118 119 @return true for values other than infinities and NaN 120 */ isFiniteSkPoint3121 bool isFinite() const { 122 SkScalar accum = 0; 123 accum *= fX; 124 accum *= fY; 125 accum *= fZ; 126 127 // accum is either NaN or it is finite (zero). 128 SkASSERT(0 == accum || SkScalarIsNaN(accum)); 129 130 // value==value will be true iff value is not NaN 131 // TODO: is it faster to say !accum or accum==accum? 132 return !SkScalarIsNaN(accum); 133 } 134 135 /** Returns the dot product of a and b, treating them as 3D vectors 136 */ DotProductSkPoint3137 static SkScalar DotProduct(const SkPoint3& a, const SkPoint3& b) { 138 return a.fX * b.fX + a.fY * b.fY + a.fZ * b.fZ; 139 } 140 dotSkPoint3141 SkScalar dot(const SkPoint3& vec) const { 142 return DotProduct(*this, vec); 143 } 144 145 /** Returns the cross product of a and b, treating them as 3D vectors 146 */ CrossProductSkPoint3147 static SkPoint3 CrossProduct(const SkPoint3& a, const SkPoint3& b) { 148 SkPoint3 result; 149 result.fX = a.fY*b.fZ - a.fZ*b.fY; 150 result.fY = a.fZ*b.fX - a.fX*b.fZ; 151 result.fZ = a.fX*b.fY - a.fY*b.fX; 152 153 return result; 154 } 155 crossSkPoint3156 SkPoint3 cross(const SkPoint3& vec) const { 157 return CrossProduct(*this, vec); 158 } 159 }; 160 161 typedef SkPoint3 SkVector3; 162 typedef SkPoint3 SkColor3f; 163 164 #endif 165