18a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/* 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2006 The Android Open Source Project 38a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 68a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 78a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifndef SkPoint_DEFINED 98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkPoint_DEFINED 108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11c12e1b138e736f70d698f14a3ffc74af6f3d8621tomhudson@google.com#include "SkMath.h" 128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkScalar.h" 138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 14d537341e16524d1e22ac5e6c8b9c8f274ba1833crobertphillips/** \struct SkIPoint16 15d537341e16524d1e22ac5e6c8b9c8f274ba1833crobertphillips 16d537341e16524d1e22ac5e6c8b9c8f274ba1833crobertphillips SkIPoint holds two 16 bit integer coordinates 17d537341e16524d1e22ac5e6c8b9c8f274ba1833crobertphillips*/ 18d537341e16524d1e22ac5e6c8b9c8f274ba1833crobertphillipsstruct SkIPoint16 { 19d537341e16524d1e22ac5e6c8b9c8f274ba1833crobertphillips int16_t fX, fY; 20d537341e16524d1e22ac5e6c8b9c8f274ba1833crobertphillips 21d537341e16524d1e22ac5e6c8b9c8f274ba1833crobertphillips static SkIPoint16 Make(int x, int y) { 22d537341e16524d1e22ac5e6c8b9c8f274ba1833crobertphillips SkIPoint16 pt; 23d537341e16524d1e22ac5e6c8b9c8f274ba1833crobertphillips pt.set(x, y); 24d537341e16524d1e22ac5e6c8b9c8f274ba1833crobertphillips return pt; 25d537341e16524d1e22ac5e6c8b9c8f274ba1833crobertphillips } 26d537341e16524d1e22ac5e6c8b9c8f274ba1833crobertphillips 27d537341e16524d1e22ac5e6c8b9c8f274ba1833crobertphillips int16_t x() const { return fX; } 28d537341e16524d1e22ac5e6c8b9c8f274ba1833crobertphillips int16_t y() const { return fY; } 29d537341e16524d1e22ac5e6c8b9c8f274ba1833crobertphillips 30d537341e16524d1e22ac5e6c8b9c8f274ba1833crobertphillips void set(int x, int y) { 31d537341e16524d1e22ac5e6c8b9c8f274ba1833crobertphillips fX = SkToS16(x); 32d537341e16524d1e22ac5e6c8b9c8f274ba1833crobertphillips fY = SkToS16(y); 33d537341e16524d1e22ac5e6c8b9c8f274ba1833crobertphillips } 34d537341e16524d1e22ac5e6c8b9c8f274ba1833crobertphillips}; 35d537341e16524d1e22ac5e6c8b9c8f274ba1833crobertphillips 368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** \struct SkIPoint 378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIPoint holds two 32 bit integer coordinates 398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstruct SkIPoint { 418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int32_t fX, fY; 426f8f292aa768869a9e85c314b124875f57504f2creed@google.com 43ac753098e8af4a17e5df97b3a4dd0ce123f8d70creed@android.com static SkIPoint Make(int32_t x, int32_t y) { 44ac753098e8af4a17e5df97b3a4dd0ce123f8d70creed@android.com SkIPoint pt; 45ac753098e8af4a17e5df97b3a4dd0ce123f8d70creed@android.com pt.set(x, y); 46ac753098e8af4a17e5df97b3a4dd0ce123f8d70creed@android.com return pt; 47ac753098e8af4a17e5df97b3a4dd0ce123f8d70creed@android.com } 488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 496f8f292aa768869a9e85c314b124875f57504f2creed@google.com int32_t x() const { return fX; } 506f8f292aa768869a9e85c314b124875f57504f2creed@google.com int32_t y() const { return fY; } 516f8f292aa768869a9e85c314b124875f57504f2creed@google.com void setX(int32_t x) { fX = x; } 526f8f292aa768869a9e85c314b124875f57504f2creed@google.com void setY(int32_t y) { fY = y; } 536f8f292aa768869a9e85c314b124875f57504f2creed@google.com 546f8f292aa768869a9e85c314b124875f57504f2creed@google.com /** 556f8f292aa768869a9e85c314b124875f57504f2creed@google.com * Returns true iff fX and fY are both zero. 566f8f292aa768869a9e85c314b124875f57504f2creed@google.com */ 576f8f292aa768869a9e85c314b124875f57504f2creed@google.com bool isZero() const { return (fX | fY) == 0; } 586f8f292aa768869a9e85c314b124875f57504f2creed@google.com 596f8f292aa768869a9e85c314b124875f57504f2creed@google.com /** 606f8f292aa768869a9e85c314b124875f57504f2creed@google.com * Set both fX and fY to zero. Same as set(0, 0) 616f8f292aa768869a9e85c314b124875f57504f2creed@google.com */ 626f8f292aa768869a9e85c314b124875f57504f2creed@google.com void setZero() { fX = fY = 0; } 636f8f292aa768869a9e85c314b124875f57504f2creed@google.com 648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Set the x and y values of the point. */ 658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void set(int32_t x, int32_t y) { fX = x; fY = y; } 668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Rotate the point clockwise, writing the new point into dst 688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com It is legal for dst == this 698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void rotateCW(SkIPoint* dst) const; 718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Rotate the point clockwise, writing the new point back into the point 738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void rotateCW() { this->rotateCW(this); } 768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Rotate the point counter-clockwise, writing the new point into dst. 788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com It is legal for dst == this 798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void rotateCCW(SkIPoint* dst) const; 818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Rotate the point counter-clockwise, writing the new point back into 838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com the point 848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void rotateCCW() { this->rotateCCW(this); } 866f8f292aa768869a9e85c314b124875f57504f2creed@google.com 878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Negate the X and Y coordinates of the point. 888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void negate() { fX = -fX; fY = -fY; } 906f8f292aa768869a9e85c314b124875f57504f2creed@google.com 918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Return a new point whose X and Y coordinates are the negative of the 928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com original point's 938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIPoint operator-() const { 958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIPoint neg; 968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com neg.fX = -fX; 978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com neg.fY = -fY; 988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return neg; 998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Add v's coordinates to this point's */ 1028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void operator+=(const SkIPoint& v) { 1038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fX += v.fX; 1048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fY += v.fY; 1058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1066f8f292aa768869a9e85c314b124875f57504f2creed@google.com 1078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Subtract v's coordinates from this point's */ 1088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void operator-=(const SkIPoint& v) { 1098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fX -= v.fX; 1108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fY -= v.fY; 1118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Returns true if the point's coordinates equal (x,y) */ 1148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool equals(int32_t x, int32_t y) const { 1158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fX == x && fY == y; 1168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com friend bool operator==(const SkIPoint& a, const SkIPoint& b) { 1198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return a.fX == b.fX && a.fY == b.fY; 1208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1216f8f292aa768869a9e85c314b124875f57504f2creed@google.com 1228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com friend bool operator!=(const SkIPoint& a, const SkIPoint& b) { 1238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return a.fX != b.fX || a.fY != b.fY; 1248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Returns a new point whose coordinates are the difference between 1278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com a and b (i.e. a - b) 1288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 1298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com friend SkIPoint operator-(const SkIPoint& a, const SkIPoint& b) { 1308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIPoint v; 1318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com v.set(a.fX - b.fX, a.fY - b.fY); 1328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return v; 1338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Returns a new point whose coordinates are the sum of a and b (a + b) 1368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 1378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com friend SkIPoint operator+(const SkIPoint& a, const SkIPoint& b) { 1388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIPoint v; 1398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com v.set(a.fX + b.fX, a.fY + b.fY); 1408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return v; 1418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1426f8f292aa768869a9e85c314b124875f57504f2creed@google.com 1438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Returns the dot product of a and b, treating them as 2D vectors 1448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 1458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static int32_t DotProduct(const SkIPoint& a, const SkIPoint& b) { 1468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return a.fX * b.fX + a.fY * b.fY; 1478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Returns the cross product of a and b, treating them as 2D vectors 1508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 1518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static int32_t CrossProduct(const SkIPoint& a, const SkIPoint& b) { 1528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return a.fX * b.fY - a.fY * b.fX; 1538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 1558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1567ffb1b21abcc7bbed5a0fc711f6dd7b9dbb4f577ctguil@chromium.orgstruct SK_API SkPoint { 1578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar fX, fY; 1588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 159ac753098e8af4a17e5df97b3a4dd0ce123f8d70creed@android.com static SkPoint Make(SkScalar x, SkScalar y) { 160ac753098e8af4a17e5df97b3a4dd0ce123f8d70creed@android.com SkPoint pt; 161ac753098e8af4a17e5df97b3a4dd0ce123f8d70creed@android.com pt.set(x, y); 162ac753098e8af4a17e5df97b3a4dd0ce123f8d70creed@android.com return pt; 163ac753098e8af4a17e5df97b3a4dd0ce123f8d70creed@android.com } 1646f8f292aa768869a9e85c314b124875f57504f2creed@google.com 165b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org SkScalar x() const { return fX; } 166b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org SkScalar y() const { return fY; } 167b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org 168398b1bcb7d30f9e55504b6de37d31ccc1a26c876mike@reedtribe.org /** 169398b1bcb7d30f9e55504b6de37d31ccc1a26c876mike@reedtribe.org * Returns true iff fX and fY are both zero. 170398b1bcb7d30f9e55504b6de37d31ccc1a26c876mike@reedtribe.org */ 171398b1bcb7d30f9e55504b6de37d31ccc1a26c876mike@reedtribe.org bool isZero() const { return (0 == fX) & (0 == fY); } 172398b1bcb7d30f9e55504b6de37d31ccc1a26c876mike@reedtribe.org 1738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Set the point's X and Y coordinates */ 1748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void set(SkScalar x, SkScalar y) { fX = x; fY = y; } 1756f8f292aa768869a9e85c314b124875f57504f2creed@google.com 1768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Set the point's X and Y coordinates by automatically promoting (x,y) to 1778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar values. 1788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 1798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void iset(int32_t x, int32_t y) { 1808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fX = SkIntToScalar(x); 1818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fY = SkIntToScalar(y); 1828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1836f8f292aa768869a9e85c314b124875f57504f2creed@google.com 1848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Set the point's X and Y coordinates by automatically promoting p's 1858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com coordinates to SkScalar values. 1868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 1878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void iset(const SkIPoint& p) { 1888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fX = SkIntToScalar(p.fX); 1898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fY = SkIntToScalar(p.fY); 1908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1927744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com void setAbs(const SkPoint& pt) { 1937744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com fX = SkScalarAbs(pt.fX); 1947744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com fY = SkScalarAbs(pt.fY); 1957744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com } 196fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1977744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com // counter-clockwise fan 1987744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com void setIRectFan(int l, int t, int r, int b) { 1997744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com SkPoint* v = this; 2007744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com v[0].set(SkIntToScalar(l), SkIntToScalar(t)); 2017744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com v[1].set(SkIntToScalar(l), SkIntToScalar(b)); 2027744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com v[2].set(SkIntToScalar(r), SkIntToScalar(b)); 2037744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com v[3].set(SkIntToScalar(r), SkIntToScalar(t)); 2047744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com } 2057744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com void setIRectFan(int l, int t, int r, int b, size_t stride); 2067744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com 2077744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com // counter-clockwise fan 2087744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com void setRectFan(SkScalar l, SkScalar t, SkScalar r, SkScalar b) { 2097744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com SkPoint* v = this; 2107744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com v[0].set(l, t); 2117744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com v[1].set(l, b); 2127744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com v[2].set(r, b); 2137744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com v[3].set(r, t); 2147744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com } 2157744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com void setRectFan(SkScalar l, SkScalar t, SkScalar r, SkScalar b, size_t stride); 2167744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com 217dbeeac33329f5fd7dbd3514cd7189ca6ed080476bsalomon@google.com static void Offset(SkPoint points[], int count, const SkPoint& offset) { 218dbeeac33329f5fd7dbd3514cd7189ca6ed080476bsalomon@google.com Offset(points, count, offset.fX, offset.fY); 219dbeeac33329f5fd7dbd3514cd7189ca6ed080476bsalomon@google.com } 220dbeeac33329f5fd7dbd3514cd7189ca6ed080476bsalomon@google.com 221dbeeac33329f5fd7dbd3514cd7189ca6ed080476bsalomon@google.com static void Offset(SkPoint points[], int count, SkScalar dx, SkScalar dy) { 222dbeeac33329f5fd7dbd3514cd7189ca6ed080476bsalomon@google.com for (int i = 0; i < count; ++i) { 223dbeeac33329f5fd7dbd3514cd7189ca6ed080476bsalomon@google.com points[i].offset(dx, dy); 224dbeeac33329f5fd7dbd3514cd7189ca6ed080476bsalomon@google.com } 225dbeeac33329f5fd7dbd3514cd7189ca6ed080476bsalomon@google.com } 226dbeeac33329f5fd7dbd3514cd7189ca6ed080476bsalomon@google.com 2277744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com void offset(SkScalar dx, SkScalar dy) { 2287744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com fX += dx; 2297744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com fY += dy; 2307744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com } 2317744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com 2328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Return the euclidian distance from (0,0) to the point 2338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 2348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar length() const { return SkPoint::Length(fX, fY); } 2357744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com SkScalar distanceToOrigin() const { return this->length(); } 2368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23755b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com /** 23855b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com * Return true if the computed length of the vector is >= the internal 23955b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com * tolerance (used to avoid dividing by tiny values). 24055b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com */ 24111e5b972a984c7b4e09ba4dfeacc7bd805107c5acommit-bot@chromium.org static bool CanNormalize(SkScalar dx, SkScalar dy) { 24211e5b972a984c7b4e09ba4dfeacc7bd805107c5acommit-bot@chromium.org // Simple enough (and performance critical sometimes) so we inline it. 24311e5b972a984c7b4e09ba4dfeacc7bd805107c5acommit-bot@chromium.org return (dx*dx + dy*dy) > (SK_ScalarNearlyZero * SK_ScalarNearlyZero); 24411e5b972a984c7b4e09ba4dfeacc7bd805107c5acommit-bot@chromium.org } 24555b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com 24655b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com bool canNormalize() const { 24755b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com return CanNormalize(fX, fY); 24855b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com } 24955b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com 2508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Set the point (vector) to be unit-length in the same direction as it 2511fd56dc6e189ea0e94b5df9af959c243573f8883epoger@google.com already points. If the point has a degenerate length (i.e. nearly 0) 2521fd56dc6e189ea0e94b5df9af959c243573f8883epoger@google.com then return false and do nothing; otherwise return true. 2538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 2548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool normalize(); 2556f8f292aa768869a9e85c314b124875f57504f2creed@google.com 2568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Set the point (vector) to be unit-length in the same direction as the 2578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com x,y params. If the vector (x,y) has a degenerate length (i.e. nearly 0) 2588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com then return false and do nothing, otherwise return true. 2598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 2608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool setNormalize(SkScalar x, SkScalar y); 2616f8f292aa768869a9e85c314b124875f57504f2creed@google.com 2628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Scale the point (vector) to have the specified length, and return that 2638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com length. If the original length is degenerately small (nearly zero), 2648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com do nothing and return false, otherwise return true. 2658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 2668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool setLength(SkScalar length); 2676f8f292aa768869a9e85c314b124875f57504f2creed@google.com 2688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Set the point (vector) to have the specified length in the same 2698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com direction as (x,y). If the vector (x,y) has a degenerate length 2708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com (i.e. nearly 0) then return false and do nothing, otherwise return true. 2718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 2728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool setLength(SkScalar x, SkScalar y, SkScalar length); 2738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 27411e5b972a984c7b4e09ba4dfeacc7bd805107c5acommit-bot@chromium.org /** Same as setLength, but favoring speed over accuracy. 27511e5b972a984c7b4e09ba4dfeacc7bd805107c5acommit-bot@chromium.org */ 27611e5b972a984c7b4e09ba4dfeacc7bd805107c5acommit-bot@chromium.org bool setLengthFast(SkScalar length); 27711e5b972a984c7b4e09ba4dfeacc7bd805107c5acommit-bot@chromium.org 27811e5b972a984c7b4e09ba4dfeacc7bd805107c5acommit-bot@chromium.org /** Same as setLength, but favoring speed over accuracy. 27911e5b972a984c7b4e09ba4dfeacc7bd805107c5acommit-bot@chromium.org */ 28011e5b972a984c7b4e09ba4dfeacc7bd805107c5acommit-bot@chromium.org bool setLengthFast(SkScalar x, SkScalar y, SkScalar length); 28111e5b972a984c7b4e09ba4dfeacc7bd805107c5acommit-bot@chromium.org 2828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Scale the point's coordinates by scale, writing the answer into dst. 2838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com It is legal for dst == this. 2848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 2858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void scale(SkScalar scale, SkPoint* dst) const; 2866f8f292aa768869a9e85c314b124875f57504f2creed@google.com 2878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Scale the point's coordinates by scale, writing the answer back into 2888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com the point. 2898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 290fc25abdabff76f913fb9d4f373418c10a1eca92breed@android.com void scale(SkScalar value) { this->scale(value, this); } 2918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Rotate the point clockwise by 90 degrees, writing the answer into dst. 2938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com It is legal for dst == this. 2948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 2958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void rotateCW(SkPoint* dst) const; 2966f8f292aa768869a9e85c314b124875f57504f2creed@google.com 2978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Rotate the point clockwise by 90 degrees, writing the answer back into 2988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com the point. 2998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 3008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void rotateCW() { this->rotateCW(this); } 3016f8f292aa768869a9e85c314b124875f57504f2creed@google.com 3028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Rotate the point counter-clockwise by 90 degrees, writing the answer 3038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com into dst. It is legal for dst == this. 3048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 3058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void rotateCCW(SkPoint* dst) const; 3066f8f292aa768869a9e85c314b124875f57504f2creed@google.com 3078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Rotate the point counter-clockwise by 90 degrees, writing the answer 3088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com back into the point. 3098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 3108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void rotateCCW() { this->rotateCCW(this); } 3116f8f292aa768869a9e85c314b124875f57504f2creed@google.com 3128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Negate the point's coordinates 3138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 3148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void negate() { 3158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fX = -fX; 3168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fY = -fY; 3178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3186f8f292aa768869a9e85c314b124875f57504f2creed@google.com 3198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Returns a new point whose coordinates are the negative of the point's 3208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 3218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPoint operator-() const { 3228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPoint neg; 3238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com neg.fX = -fX; 3248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com neg.fY = -fY; 3258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return neg; 3268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Add v's coordinates to the point's 3298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 3308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void operator+=(const SkPoint& v) { 3318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fX += v.fX; 3328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fY += v.fY; 3338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3346f8f292aa768869a9e85c314b124875f57504f2creed@google.com 3358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Subtract v's coordinates from the point's 3368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 3378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void operator-=(const SkPoint& v) { 3388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fX -= v.fX; 3398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fY -= v.fY; 3408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3420bb18bb264b26afca45452910437c09445e23a3creed@google.com /** 3430bb18bb264b26afca45452910437c09445e23a3creed@google.com * Returns true if both X and Y are finite (not infinity or NaN) 3440bb18bb264b26afca45452910437c09445e23a3creed@google.com */ 3450bb18bb264b26afca45452910437c09445e23a3creed@google.com bool isFinite() const { 3460bb18bb264b26afca45452910437c09445e23a3creed@google.com SkScalar accum = 0; 3470bb18bb264b26afca45452910437c09445e23a3creed@google.com accum *= fX; 3480bb18bb264b26afca45452910437c09445e23a3creed@google.com accum *= fY; 349fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 3500bb18bb264b26afca45452910437c09445e23a3creed@google.com // accum is either NaN or it is finite (zero). 3510bb18bb264b26afca45452910437c09445e23a3creed@google.com SkASSERT(0 == accum || !(accum == accum)); 352fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 3530bb18bb264b26afca45452910437c09445e23a3creed@google.com // value==value will be true iff value is not NaN 3540bb18bb264b26afca45452910437c09445e23a3creed@google.com // TODO: is it faster to say !accum or accum==accum? 3550bb18bb264b26afca45452910437c09445e23a3creed@google.com return accum == accum; 3560bb18bb264b26afca45452910437c09445e23a3creed@google.com } 3570bb18bb264b26afca45452910437c09445e23a3creed@google.com 35824d10cb635b002462dc503bf603d3ec487fcb557reed@google.com /** 35924d10cb635b002462dc503bf603d3ec487fcb557reed@google.com * Returns true if the point's coordinates equal (x,y) 36024d10cb635b002462dc503bf603d3ec487fcb557reed@google.com */ 36124d10cb635b002462dc503bf603d3ec487fcb557reed@google.com bool equals(SkScalar x, SkScalar y) const { 36224d10cb635b002462dc503bf603d3ec487fcb557reed@google.com return fX == x && fY == y; 36324d10cb635b002462dc503bf603d3ec487fcb557reed@google.com } 3648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com friend bool operator==(const SkPoint& a, const SkPoint& b) { 3668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return a.fX == b.fX && a.fY == b.fY; 3678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3686f8f292aa768869a9e85c314b124875f57504f2creed@google.com 3698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com friend bool operator!=(const SkPoint& a, const SkPoint& b) { 3708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return a.fX != b.fX || a.fY != b.fY; 3718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 37394fa43c6255906660c2ff001fb462b6492cbdc07epoger@google.com /** Return true if this point and the given point are far enough apart 37494fa43c6255906660c2ff001fb462b6492cbdc07epoger@google.com such that a vector between them would be non-degenerate. 37594fa43c6255906660c2ff001fb462b6492cbdc07epoger@google.com 3764469938e92d779dff05e745559e67907bbf21e78reed@google.com WARNING: Unlike the explicit tolerance version, 37794fa43c6255906660c2ff001fb462b6492cbdc07epoger@google.com this method does not use componentwise comparison. Instead, it 37894fa43c6255906660c2ff001fb462b6492cbdc07epoger@google.com uses a comparison designed to match judgments elsewhere regarding 37994fa43c6255906660c2ff001fb462b6492cbdc07epoger@google.com degeneracy ("points A and B are so close that the vector between them 38094fa43c6255906660c2ff001fb462b6492cbdc07epoger@google.com is essentially zero"). 3814da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org */ 38294fa43c6255906660c2ff001fb462b6492cbdc07epoger@google.com bool equalsWithinTolerance(const SkPoint& p) const { 38394fa43c6255906660c2ff001fb462b6492cbdc07epoger@google.com return !CanNormalize(fX - p.fX, fY - p.fY); 38494fa43c6255906660c2ff001fb462b6492cbdc07epoger@google.com } 38594fa43c6255906660c2ff001fb462b6492cbdc07epoger@google.com 3864469938e92d779dff05e745559e67907bbf21e78reed@google.com /** WARNING: There is no guarantee that the result will reflect judgments 38794fa43c6255906660c2ff001fb462b6492cbdc07epoger@google.com elsewhere regarding degeneracy ("points A and B are so close that the 38894fa43c6255906660c2ff001fb462b6492cbdc07epoger@google.com vector between them is essentially zero"). 38994fa43c6255906660c2ff001fb462b6492cbdc07epoger@google.com */ 39094fa43c6255906660c2ff001fb462b6492cbdc07epoger@google.com bool equalsWithinTolerance(const SkPoint& p, SkScalar tol) const { 39194fa43c6255906660c2ff001fb462b6492cbdc07epoger@google.com return SkScalarNearlyZero(fX - p.fX, tol) 39294fa43c6255906660c2ff001fb462b6492cbdc07epoger@google.com && SkScalarNearlyZero(fY - p.fY, tol); 3934da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org } 3944da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org 3958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Returns a new point whose coordinates are the difference between 3968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com a's and b's (a - b) 3978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 3988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com friend SkPoint operator-(const SkPoint& a, const SkPoint& b) { 3998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPoint v; 4008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com v.set(a.fX - b.fX, a.fY - b.fY); 4018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return v; 4028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 4038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Returns a new point whose coordinates are the sum of a's and b's (a + b) 4058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 4068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com friend SkPoint operator+(const SkPoint& a, const SkPoint& b) { 4078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPoint v; 4088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com v.set(a.fX + b.fX, a.fY + b.fY); 4098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return v; 4108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 4118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Returns the euclidian distance from (0,0) to (x,y) 4138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 4148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static SkScalar Length(SkScalar x, SkScalar y); 415ac753098e8af4a17e5df97b3a4dd0ce123f8d70creed@android.com 416ac753098e8af4a17e5df97b3a4dd0ce123f8d70creed@android.com /** Normalize pt, returning its previous length. If the prev length is too 41755b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com small (degenerate), return 0 and leave pt unchanged. This uses the same 41855b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com tolerance as CanNormalize. 4191fd56dc6e189ea0e94b5df9af959c243573f8883epoger@google.com 4201fd56dc6e189ea0e94b5df9af959c243573f8883epoger@google.com Note that this method may be significantly more expensive than 4211fd56dc6e189ea0e94b5df9af959c243573f8883epoger@google.com the non-static normalize(), because it has to return the previous length 4221fd56dc6e189ea0e94b5df9af959c243573f8883epoger@google.com of the point. If you don't need the previous length, call the 4231fd56dc6e189ea0e94b5df9af959c243573f8883epoger@google.com non-static normalize() method instead. 424ac753098e8af4a17e5df97b3a4dd0ce123f8d70creed@android.com */ 425ac753098e8af4a17e5df97b3a4dd0ce123f8d70creed@android.com static SkScalar Normalize(SkPoint* pt); 426ac753098e8af4a17e5df97b3a4dd0ce123f8d70creed@android.com 4278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Returns the euclidian distance between a and b 4288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 4298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static SkScalar Distance(const SkPoint& a, const SkPoint& b) { 4308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return Length(a.fX - b.fX, a.fY - b.fY); 4318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 4328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Returns the dot product of a and b, treating them as 2D vectors 4348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 4358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static SkScalar DotProduct(const SkPoint& a, const SkPoint& b) { 4361a5e51f94ed8cb01600184119e52bb64bdb3dcccreed@google.com return a.fX * b.fX + a.fY * b.fY; 4378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 4388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Returns the cross product of a and b, treating them as 2D vectors 4408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 4418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static SkScalar CrossProduct(const SkPoint& a, const SkPoint& b) { 4421a5e51f94ed8cb01600184119e52bb64bdb3dcccreed@google.com return a.fX * b.fY - a.fY * b.fX; 4438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 4447744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com 4457744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com SkScalar cross(const SkPoint& vec) const { 4467744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com return CrossProduct(*this, vec); 4477744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com } 4487744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com 4497744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com SkScalar dot(const SkPoint& vec) const { 4507744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com return DotProduct(*this, vec); 4517744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com } 452fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 4537744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com SkScalar lengthSqd() const { 4547744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com return DotProduct(*this, *this); 4557744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com } 456fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 4577744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com SkScalar distanceToSqd(const SkPoint& pt) const { 4587744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com SkScalar dx = fX - pt.fX; 4597744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com SkScalar dy = fY - pt.fY; 4601a5e51f94ed8cb01600184119e52bb64bdb3dcccreed@google.com return dx * dx + dy * dy; 4617744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com } 462647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com 463647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com /** 464647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com * The side of a point relative to a line. If the line is from a to b then 465647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com * the values are consistent with the sign of (b-a) cross (pt-a) 466647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com */ 467647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com enum Side { 468647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com kLeft_Side = -1, 469647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com kOn_Side = 0, 470647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com kRight_Side = 1 471647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com }; 472647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com 473647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com /** 474647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com * Returns the squared distance to the infinite line between two pts. Also 475647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com * optionally returns the side of the line that the pt falls on (looking 476647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com * along line from a to b) 477647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com */ 478647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com SkScalar distanceToLineBetweenSqd(const SkPoint& a, 479647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com const SkPoint& b, 480647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com Side* side = NULL) const; 481647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com 482647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com /** 483647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com * Returns the distance to the infinite line between two pts. Also 484647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com * optionally returns the side of the line that the pt falls on (looking 485647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com * along the line from a to b) 486647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com */ 487647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com SkScalar distanceToLineBetween(const SkPoint& a, 488647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com const SkPoint& b, 489647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com Side* side = NULL) const { 490647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com return SkScalarSqrt(this->distanceToLineBetweenSqd(a, b, side)); 491647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com } 492647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com 493647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com /** 494647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com * Returns the squared distance to the line segment between pts a and b 495647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com */ 496647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com SkScalar distanceToLineSegmentBetweenSqd(const SkPoint& a, 4977744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com const SkPoint& b) const; 498647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com 499647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com /** 500647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com * Returns the distance to the line segment between pts a and b. 501647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com */ 502647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com SkScalar distanceToLineSegmentBetween(const SkPoint& a, 5037744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com const SkPoint& b) const { 5047744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com return SkScalarSqrt(this->distanceToLineSegmentBetweenSqd(a, b)); 5057744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com } 506647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com 507647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com /** 508647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com * Make this vector be orthogonal to vec. Looking down vec the 509647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com * new vector will point in direction indicated by side (which 510647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com * must be kLeft_Side or kRight_Side). 511647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com */ 512647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com void setOrthog(const SkPoint& vec, Side side = kLeft_Side) { 513647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com // vec could be this 514647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com SkScalar tmp = vec.fX; 515278dc6929b6481204874dcfcc055e2aaa30a95b2bsalomon@google.com if (kRight_Side == side) { 516647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com fX = -vec.fY; 517647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com fY = tmp; 518647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com } else { 519278dc6929b6481204874dcfcc055e2aaa30a95b2bsalomon@google.com SkASSERT(kLeft_Side == side); 520647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com fX = vec.fY; 521647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com fY = -tmp; 522647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com } 523647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com } 524c7d0ea3cd328566958bfcb86b4488dcbb94dd5ecreed@google.com 525c7d0ea3cd328566958bfcb86b4488dcbb94dd5ecreed@google.com /** 526c7d0ea3cd328566958bfcb86b4488dcbb94dd5ecreed@google.com * cast-safe way to treat the point as an array of (2) SkScalars. 527c7d0ea3cd328566958bfcb86b4488dcbb94dd5ecreed@google.com */ 528c7d0ea3cd328566958bfcb86b4488dcbb94dd5ecreed@google.com const SkScalar* asScalars() const { return &fX; } 5298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 5308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comtypedef SkPoint SkVector; 5328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 534