Home | History | Annotate | Download | only in core
      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