1 /* 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 */ 27 struct SkIPoint { 28 int32_t fX, fY; 29 30 static SkIPoint Make(int32_t x, int32_t y) { 31 SkIPoint pt; 32 pt.set(x, y); 33 return pt; 34 } 35 36 /** Set the x and y values of the point. */ 37 void set(int32_t x, int32_t y) { fX = x; fY = y; } 38 39 /** Rotate the point clockwise, writing the new point into dst 40 It is legal for dst == this 41 */ 42 void rotateCW(SkIPoint* dst) const; 43 44 /** Rotate the point clockwise, writing the new point back into the point 45 */ 46 47 void rotateCW() { this->rotateCW(this); } 48 49 /** Rotate the point counter-clockwise, writing the new point into dst. 50 It is legal for dst == this 51 */ 52 void rotateCCW(SkIPoint* dst) const; 53 54 /** Rotate the point counter-clockwise, writing the new point back into 55 the point 56 */ 57 void rotateCCW() { this->rotateCCW(this); } 58 59 /** Negate the X and Y coordinates of the point. 60 */ 61 void negate() { fX = -fX; fY = -fY; } 62 63 /** Return a new point whose X and Y coordinates are the negative of the 64 original point's 65 */ 66 SkIPoint operator-() const { 67 SkIPoint neg; 68 neg.fX = -fX; 69 neg.fY = -fY; 70 return neg; 71 } 72 73 /** Add v's coordinates to this point's */ 74 void operator+=(const SkIPoint& v) { 75 fX += v.fX; 76 fY += v.fY; 77 } 78 79 /** Subtract v's coordinates from this point's */ 80 void operator-=(const SkIPoint& v) { 81 fX -= v.fX; 82 fY -= v.fY; 83 } 84 85 /** Returns true if the point's coordinates equal (x,y) */ 86 bool equals(int32_t x, int32_t y) const { 87 return fX == x && fY == y; 88 } 89 90 friend bool operator==(const SkIPoint& a, const SkIPoint& b) { 91 return a.fX == b.fX && a.fY == b.fY; 92 } 93 94 friend bool operator!=(const SkIPoint& a, const SkIPoint& b) { 95 return a.fX != b.fX || a.fY != b.fY; 96 } 97 98 /** Returns a new point whose coordinates are the difference between 99 a and b (i.e. a - b) 100 */ 101 friend SkIPoint operator-(const SkIPoint& a, const SkIPoint& b) { 102 SkIPoint v; 103 v.set(a.fX - b.fX, a.fY - b.fY); 104 return v; 105 } 106 107 /** Returns a new point whose coordinates are the sum of a and b (a + b) 108 */ 109 friend SkIPoint operator+(const SkIPoint& a, const SkIPoint& b) { 110 SkIPoint v; 111 v.set(a.fX + b.fX, a.fY + b.fY); 112 return v; 113 } 114 115 /** Returns the dot product of a and b, treating them as 2D vectors 116 */ 117 static int32_t DotProduct(const SkIPoint& a, const SkIPoint& b) { 118 return a.fX * b.fX + a.fY * b.fY; 119 } 120 121 /** Returns the cross product of a and b, treating them as 2D vectors 122 */ 123 static int32_t CrossProduct(const SkIPoint& a, const SkIPoint& b) { 124 return a.fX * b.fY - a.fY * b.fX; 125 } 126 }; 127 128 struct SkPoint { 129 SkScalar fX, fY; 130 131 static SkPoint Make(SkScalar x, SkScalar y) { 132 SkPoint pt; 133 pt.set(x, y); 134 return pt; 135 } 136 137 /** Set the point's X and Y coordinates */ 138 void set(SkScalar x, SkScalar y) { fX = x; fY = y; } 139 140 /** Set the point's X and Y coordinates by automatically promoting (x,y) to 141 SkScalar values. 142 */ 143 void iset(int32_t x, int32_t y) { 144 fX = SkIntToScalar(x); 145 fY = SkIntToScalar(y); 146 } 147 148 /** Set the point's X and Y coordinates by automatically promoting p's 149 coordinates to SkScalar values. 150 */ 151 void iset(const SkIPoint& p) { 152 fX = SkIntToScalar(p.fX); 153 fY = SkIntToScalar(p.fY); 154 } 155 156 /** Return the euclidian distance from (0,0) to the point 157 */ 158 SkScalar length() const { return SkPoint::Length(fX, fY); } 159 160 /** Set the point (vector) to be unit-length in the same direction as it 161 currently is, and return its old length. If the old length is 162 degenerately small (nearly zero), do nothing and return false, otherwise 163 return true. 164 */ 165 bool normalize(); 166 167 /** Set the point (vector) to be unit-length in the same direction as the 168 x,y params. If the vector (x,y) has a degenerate length (i.e. nearly 0) 169 then return false and do nothing, otherwise return true. 170 */ 171 bool setNormalize(SkScalar x, SkScalar y); 172 173 /** Scale the point (vector) to have the specified length, and return that 174 length. If the original length is degenerately small (nearly zero), 175 do nothing and return false, otherwise return true. 176 */ 177 bool setLength(SkScalar length); 178 179 /** Set the point (vector) to have the specified length in the same 180 direction as (x,y). If the vector (x,y) has a degenerate length 181 (i.e. nearly 0) then return false and do nothing, otherwise return true. 182 */ 183 bool setLength(SkScalar x, SkScalar y, SkScalar length); 184 185 /** Scale the point's coordinates by scale, writing the answer into dst. 186 It is legal for dst == this. 187 */ 188 void scale(SkScalar scale, SkPoint* dst) const; 189 190 /** Scale the point's coordinates by scale, writing the answer back into 191 the point. 192 */ 193 void scale(SkScalar value) { this->scale(value, this); } 194 195 /** Rotate the point clockwise by 90 degrees, writing the answer into dst. 196 It is legal for dst == this. 197 */ 198 void rotateCW(SkPoint* dst) const; 199 200 /** Rotate the point clockwise by 90 degrees, writing the answer back into 201 the point. 202 */ 203 void rotateCW() { this->rotateCW(this); } 204 205 /** Rotate the point counter-clockwise by 90 degrees, writing the answer 206 into dst. It is legal for dst == this. 207 */ 208 void rotateCCW(SkPoint* dst) const; 209 210 /** Rotate the point counter-clockwise by 90 degrees, writing the answer 211 back into the point. 212 */ 213 void rotateCCW() { this->rotateCCW(this); } 214 215 /** Negate the point's coordinates 216 */ 217 void negate() { 218 fX = -fX; 219 fY = -fY; 220 } 221 222 /** Returns a new point whose coordinates are the negative of the point's 223 */ 224 SkPoint operator-() const { 225 SkPoint neg; 226 neg.fX = -fX; 227 neg.fY = -fY; 228 return neg; 229 } 230 231 /** Add v's coordinates to the point's 232 */ 233 void operator+=(const SkPoint& v) { 234 fX += v.fX; 235 fY += v.fY; 236 } 237 238 /** Subtract v's coordinates from the point's 239 */ 240 void operator-=(const SkPoint& v) { 241 fX -= v.fX; 242 fY -= v.fY; 243 } 244 245 /** Returns true if the point's coordinates equal (x,y) 246 */ 247 bool equals(SkScalar x, SkScalar y) const { return fX == x && fY == y; } 248 249 friend bool operator==(const SkPoint& a, const SkPoint& b) { 250 return a.fX == b.fX && a.fY == b.fY; 251 } 252 253 friend bool operator!=(const SkPoint& a, const SkPoint& b) { 254 return a.fX != b.fX || a.fY != b.fY; 255 } 256 257 /** Returns a new point whose coordinates are the difference between 258 a's and b's (a - b) 259 */ 260 friend SkPoint operator-(const SkPoint& a, const SkPoint& b) { 261 SkPoint v; 262 v.set(a.fX - b.fX, a.fY - b.fY); 263 return v; 264 } 265 266 /** Returns a new point whose coordinates are the sum of a's and b's (a + b) 267 */ 268 friend SkPoint operator+(const SkPoint& a, const SkPoint& b) { 269 SkPoint v; 270 v.set(a.fX + b.fX, a.fY + b.fY); 271 return v; 272 } 273 274 /** Returns the euclidian distance from (0,0) to (x,y) 275 */ 276 static SkScalar Length(SkScalar x, SkScalar y); 277 278 /** Normalize pt, returning its previous length. If the prev length is too 279 small (degenerate), return 0 and leave pt unchanged. 280 */ 281 static SkScalar Normalize(SkPoint* pt); 282 283 /** Returns the euclidian distance between a and b 284 */ 285 static SkScalar Distance(const SkPoint& a, const SkPoint& b) { 286 return Length(a.fX - b.fX, a.fY - b.fY); 287 } 288 289 /** Returns the dot product of a and b, treating them as 2D vectors 290 */ 291 static SkScalar DotProduct(const SkPoint& a, const SkPoint& b) { 292 return SkScalarMul(a.fX, b.fX) + SkScalarMul(a.fY, b.fY); 293 } 294 295 /** Returns the cross product of a and b, treating them as 2D vectors 296 */ 297 static SkScalar CrossProduct(const SkPoint& a, const SkPoint& b) { 298 return SkScalarMul(a.fX, b.fY) - SkScalarMul(a.fY, b.fX); 299 } 300 }; 301 302 typedef SkPoint SkVector; 303 304 #endif 305 306