SkPoint.h revision 7ffb1b21abcc7bbed5a0fc711f6dd7b9dbb4f577
18a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/*
28a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * Copyright (C) 2006 The Android Open Source Project
38a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *
48a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * Licensed under the Apache License, Version 2.0 (the "License");
58a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * you may not use this file except in compliance with the License.
68a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * You may obtain a copy of the License at
78a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *
88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *      http://www.apache.org/licenses/LICENSE-2.0
98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *
108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * Unless required by applicable law or agreed to in writing, software
118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * distributed under the License is distributed on an "AS IS" BASIS,
128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * See the License for the specific language governing permissions and
148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * limitations under the License.
158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */
168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifndef SkPoint_DEFINED
188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkPoint_DEFINED
198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkMath.h"
218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkScalar.h"
228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** \struct SkIPoint
248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkIPoint holds two 32 bit integer coordinates
268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/
278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstruct SkIPoint {
288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int32_t fX, fY;
296f8f292aa768869a9e85c314b124875f57504f2creed@google.com
30ac753098e8af4a17e5df97b3a4dd0ce123f8d70creed@android.com    static SkIPoint Make(int32_t x, int32_t y) {
31ac753098e8af4a17e5df97b3a4dd0ce123f8d70creed@android.com        SkIPoint pt;
32ac753098e8af4a17e5df97b3a4dd0ce123f8d70creed@android.com        pt.set(x, y);
33ac753098e8af4a17e5df97b3a4dd0ce123f8d70creed@android.com        return pt;
34ac753098e8af4a17e5df97b3a4dd0ce123f8d70creed@android.com    }
358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
366f8f292aa768869a9e85c314b124875f57504f2creed@google.com    int32_t x() const { return fX; }
376f8f292aa768869a9e85c314b124875f57504f2creed@google.com    int32_t y() const { return fY; }
386f8f292aa768869a9e85c314b124875f57504f2creed@google.com    void setX(int32_t x) { fX = x; }
396f8f292aa768869a9e85c314b124875f57504f2creed@google.com    void setY(int32_t y) { fY = y; }
406f8f292aa768869a9e85c314b124875f57504f2creed@google.com
416f8f292aa768869a9e85c314b124875f57504f2creed@google.com    /**
426f8f292aa768869a9e85c314b124875f57504f2creed@google.com     *  Returns true iff fX and fY are both zero.
436f8f292aa768869a9e85c314b124875f57504f2creed@google.com     */
446f8f292aa768869a9e85c314b124875f57504f2creed@google.com    bool isZero() const { return (fX | fY) == 0; }
456f8f292aa768869a9e85c314b124875f57504f2creed@google.com
466f8f292aa768869a9e85c314b124875f57504f2creed@google.com    /**
476f8f292aa768869a9e85c314b124875f57504f2creed@google.com     *  Set both fX and fY to zero. Same as set(0, 0)
486f8f292aa768869a9e85c314b124875f57504f2creed@google.com     */
496f8f292aa768869a9e85c314b124875f57504f2creed@google.com    void setZero() { fX = fY = 0; }
506f8f292aa768869a9e85c314b124875f57504f2creed@google.com
518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Set the x and y values of the point. */
528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void set(int32_t x, int32_t y) { fX = x; fY = y; }
538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Rotate the point clockwise, writing the new point into dst
558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        It is legal for dst == this
568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void rotateCW(SkIPoint* dst) const;
588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Rotate the point clockwise, writing the new point back into the point
608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void rotateCW() { this->rotateCW(this); }
638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Rotate the point counter-clockwise, writing the new point into dst.
658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        It is legal for dst == this
668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void rotateCCW(SkIPoint* dst) const;
688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Rotate the point counter-clockwise, writing the new point back into
708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        the point
718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void rotateCCW() { this->rotateCCW(this); }
736f8f292aa768869a9e85c314b124875f57504f2creed@google.com
748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Negate the X and Y coordinates of the point.
758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void negate() { fX = -fX; fY = -fY; }
776f8f292aa768869a9e85c314b124875f57504f2creed@google.com
788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Return a new point whose X and Y coordinates are the negative of the
798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        original point's
808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkIPoint operator-() const {
828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkIPoint neg;
838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        neg.fX = -fX;
848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        neg.fY = -fY;
858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return neg;
868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Add v's coordinates to this point's */
898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void operator+=(const SkIPoint& v) {
908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fX += v.fX;
918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fY += v.fY;
928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
936f8f292aa768869a9e85c314b124875f57504f2creed@google.com
948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Subtract v's coordinates from this point's */
958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void operator-=(const SkIPoint& v) {
968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fX -= v.fX;
978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fY -= v.fY;
988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Returns true if the point's coordinates equal (x,y) */
1018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    bool equals(int32_t x, int32_t y) const {
1028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return fX == x && fY == y;
1038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    friend bool operator==(const SkIPoint& a, const SkIPoint& b) {
1068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return a.fX == b.fX && a.fY == b.fY;
1078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1086f8f292aa768869a9e85c314b124875f57504f2creed@google.com
1098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    friend bool operator!=(const SkIPoint& a, const SkIPoint& b) {
1108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return a.fX != b.fX || a.fY != b.fY;
1118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Returns a new point whose coordinates are the difference between
1148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        a and b (i.e. a - b)
1158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
1168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    friend SkIPoint operator-(const SkIPoint& a, const SkIPoint& b) {
1178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkIPoint v;
1188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        v.set(a.fX - b.fX, a.fY - b.fY);
1198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return v;
1208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Returns a new point whose coordinates are the sum of a and b (a + b)
1238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
1248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    friend SkIPoint operator+(const SkIPoint& a, const SkIPoint& b) {
1258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkIPoint v;
1268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        v.set(a.fX + b.fX, a.fY + b.fY);
1278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return v;
1288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1296f8f292aa768869a9e85c314b124875f57504f2creed@google.com
1308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Returns the dot product of a and b, treating them as 2D vectors
1318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
1328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    static int32_t DotProduct(const SkIPoint& a, const SkIPoint& b) {
1338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return a.fX * b.fX + a.fY * b.fY;
1348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Returns the cross product of a and b, treating them as 2D vectors
1378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
1388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    static int32_t CrossProduct(const SkIPoint& a, const SkIPoint& b) {
1398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return a.fX * b.fY - a.fY * b.fX;
1408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
1428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1437ffb1b21abcc7bbed5a0fc711f6dd7b9dbb4f577ctguil@chromium.orgstruct SK_API SkPoint {
1448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkScalar    fX, fY;
1458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
146ac753098e8af4a17e5df97b3a4dd0ce123f8d70creed@android.com    static SkPoint Make(SkScalar x, SkScalar y) {
147ac753098e8af4a17e5df97b3a4dd0ce123f8d70creed@android.com        SkPoint pt;
148ac753098e8af4a17e5df97b3a4dd0ce123f8d70creed@android.com        pt.set(x, y);
149ac753098e8af4a17e5df97b3a4dd0ce123f8d70creed@android.com        return pt;
150ac753098e8af4a17e5df97b3a4dd0ce123f8d70creed@android.com    }
1516f8f292aa768869a9e85c314b124875f57504f2creed@google.com
1528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Set the point's X and Y coordinates */
1538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void set(SkScalar x, SkScalar y) { fX = x; fY = y; }
1546f8f292aa768869a9e85c314b124875f57504f2creed@google.com
1558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Set the point's X and Y coordinates by automatically promoting (x,y) to
1568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkScalar values.
1578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
1588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void iset(int32_t x, int32_t y) {
1598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fX = SkIntToScalar(x);
1608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fY = SkIntToScalar(y);
1618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1626f8f292aa768869a9e85c314b124875f57504f2creed@google.com
1638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Set the point's X and Y coordinates by automatically promoting p's
1648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        coordinates to SkScalar values.
1658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
1668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void iset(const SkIPoint& p) {
1678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fX = SkIntToScalar(p.fX);
1688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fY = SkIntToScalar(p.fY);
1698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Return the euclidian distance from (0,0) to the point
1728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
1738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkScalar length() const { return SkPoint::Length(fX, fY); }
1748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Set the point (vector) to be unit-length in the same direction as it
1768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        currently is, and return its old length. If the old length is
1778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        degenerately small (nearly zero), do nothing and return false, otherwise
1788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return true.
1798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
1808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    bool normalize();
1816f8f292aa768869a9e85c314b124875f57504f2creed@google.com
1828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Set the point (vector) to be unit-length in the same direction as the
1838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        x,y params. If the vector (x,y) has a degenerate length (i.e. nearly 0)
1848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        then return false and do nothing, otherwise return true.
1858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
1868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    bool setNormalize(SkScalar x, SkScalar y);
1876f8f292aa768869a9e85c314b124875f57504f2creed@google.com
1888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Scale the point (vector) to have the specified length, and return that
1898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        length. If the original length is degenerately small (nearly zero),
1908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        do nothing and return false, otherwise return true.
1918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
1928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    bool setLength(SkScalar length);
1936f8f292aa768869a9e85c314b124875f57504f2creed@google.com
1948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Set the point (vector) to have the specified length in the same
1958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     direction as (x,y). If the vector (x,y) has a degenerate length
1968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     (i.e. nearly 0) then return false and do nothing, otherwise return true.
1978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
1988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    bool setLength(SkScalar x, SkScalar y, SkScalar length);
1998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Scale the point's coordinates by scale, writing the answer into dst.
2018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        It is legal for dst == this.
2028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
2038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void scale(SkScalar scale, SkPoint* dst) const;
2046f8f292aa768869a9e85c314b124875f57504f2creed@google.com
2058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Scale the point's coordinates by scale, writing the answer back into
2068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        the point.
2078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
208fc25abdabff76f913fb9d4f373418c10a1eca92breed@android.com    void scale(SkScalar value) { this->scale(value, this); }
2098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Rotate the point clockwise by 90 degrees, writing the answer into dst.
2118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        It is legal for dst == this.
2128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
2138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void rotateCW(SkPoint* dst) const;
2146f8f292aa768869a9e85c314b124875f57504f2creed@google.com
2158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Rotate the point clockwise by 90 degrees, writing the answer back into
2168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        the point.
2178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
2188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void rotateCW() { this->rotateCW(this); }
2196f8f292aa768869a9e85c314b124875f57504f2creed@google.com
2208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Rotate the point counter-clockwise by 90 degrees, writing the answer
2218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        into dst. It is legal for dst == this.
2228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
2238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void rotateCCW(SkPoint* dst) const;
2246f8f292aa768869a9e85c314b124875f57504f2creed@google.com
2258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Rotate the point counter-clockwise by 90 degrees, writing the answer
2268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        back into the point.
2278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
2288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void rotateCCW() { this->rotateCCW(this); }
2296f8f292aa768869a9e85c314b124875f57504f2creed@google.com
2308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Negate the point's coordinates
2318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
2328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void negate() {
2338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fX = -fX;
2348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fY = -fY;
2358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
2366f8f292aa768869a9e85c314b124875f57504f2creed@google.com
2378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Returns a new point whose coordinates are the negative of the point's
2388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
2398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkPoint operator-() const {
2408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkPoint neg;
2418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        neg.fX = -fX;
2428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        neg.fY = -fY;
2438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return neg;
2448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
2458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Add v's coordinates to the point's
2478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
2488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void operator+=(const SkPoint& v) {
2498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fX += v.fX;
2508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fY += v.fY;
2518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
2526f8f292aa768869a9e85c314b124875f57504f2creed@google.com
2538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Subtract v's coordinates from the point's
2548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
2558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void operator-=(const SkPoint& v) {
2568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fX -= v.fX;
2578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fY -= v.fY;
2588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
2598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Returns true if the point's coordinates equal (x,y)
2618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
2628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    bool equals(SkScalar x, SkScalar y) const { return fX == x && fY == y; }
2638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    friend bool operator==(const SkPoint& a, const SkPoint& b) {
2658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return a.fX == b.fX && a.fY == b.fY;
2668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
2676f8f292aa768869a9e85c314b124875f57504f2creed@google.com
2688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    friend bool operator!=(const SkPoint& a, const SkPoint& b) {
2698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return a.fX != b.fX || a.fY != b.fY;
2708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
2718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Returns a new point whose coordinates are the difference between
2738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        a's and b's (a - b)
2748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
2758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    friend SkPoint operator-(const SkPoint& a, const SkPoint& b) {
2768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkPoint v;
2778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        v.set(a.fX - b.fX, a.fY - b.fY);
2788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return v;
2798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
2808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Returns a new point whose coordinates are the sum of a's and b's (a + b)
2828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
2838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    friend SkPoint operator+(const SkPoint& a, const SkPoint& b) {
2848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkPoint v;
2858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        v.set(a.fX + b.fX, a.fY + b.fY);
2868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return v;
2878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
2888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Returns the euclidian distance from (0,0) to (x,y)
2908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
2918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    static SkScalar Length(SkScalar x, SkScalar y);
292ac753098e8af4a17e5df97b3a4dd0ce123f8d70creed@android.com
293ac753098e8af4a17e5df97b3a4dd0ce123f8d70creed@android.com    /** Normalize pt, returning its previous length. If the prev length is too
294ac753098e8af4a17e5df97b3a4dd0ce123f8d70creed@android.com        small (degenerate), return 0 and leave pt unchanged.
295ac753098e8af4a17e5df97b3a4dd0ce123f8d70creed@android.com     */
296ac753098e8af4a17e5df97b3a4dd0ce123f8d70creed@android.com    static SkScalar Normalize(SkPoint* pt);
297ac753098e8af4a17e5df97b3a4dd0ce123f8d70creed@android.com
2988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Returns the euclidian distance between a and b
2998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
3008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    static SkScalar Distance(const SkPoint& a, const SkPoint& b) {
3018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return Length(a.fX - b.fX, a.fY - b.fY);
3028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
3038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Returns the dot product of a and b, treating them as 2D vectors
3058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
3068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    static SkScalar DotProduct(const SkPoint& a, const SkPoint& b) {
3078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return SkScalarMul(a.fX, b.fX) + SkScalarMul(a.fY, b.fY);
3088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
3098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Returns the cross product of a and b, treating them as 2D vectors
3118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
3128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    static SkScalar CrossProduct(const SkPoint& a, const SkPoint& b) {
3138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return SkScalarMul(a.fX, b.fY) - SkScalarMul(a.fY, b.fX);
3148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
3158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
3168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comtypedef SkPoint SkVector;
3188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif
3208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
321