1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/src/pathops/SkPathOpsPoint.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,213 @@ 1.4 +/* 1.5 + * Copyright 2012 Google Inc. 1.6 + * 1.7 + * Use of this source code is governed by a BSD-style license that can be 1.8 + * found in the LICENSE file. 1.9 + */ 1.10 +#ifndef SkPathOpsPoint_DEFINED 1.11 +#define SkPathOpsPoint_DEFINED 1.12 + 1.13 +#include "SkPathOpsTypes.h" 1.14 +#include "SkPoint.h" 1.15 + 1.16 +inline bool AlmostEqualUlps(const SkPoint& pt1, const SkPoint& pt2) { 1.17 + return AlmostEqualUlps(pt1.fX, pt2.fX) && AlmostEqualUlps(pt1.fY, pt2.fY); 1.18 +} 1.19 + 1.20 +struct SkDVector { 1.21 + double fX, fY; 1.22 + 1.23 + friend SkDPoint operator+(const SkDPoint& a, const SkDVector& b); 1.24 + 1.25 + void operator+=(const SkDVector& v) { 1.26 + fX += v.fX; 1.27 + fY += v.fY; 1.28 + } 1.29 + 1.30 + void operator-=(const SkDVector& v) { 1.31 + fX -= v.fX; 1.32 + fY -= v.fY; 1.33 + } 1.34 + 1.35 + void operator/=(const double s) { 1.36 + fX /= s; 1.37 + fY /= s; 1.38 + } 1.39 + 1.40 + void operator*=(const double s) { 1.41 + fX *= s; 1.42 + fY *= s; 1.43 + } 1.44 + 1.45 + SkVector asSkVector() const { 1.46 + SkVector v = {SkDoubleToScalar(fX), SkDoubleToScalar(fY)}; 1.47 + return v; 1.48 + } 1.49 + 1.50 + double cross(const SkDVector& a) const { 1.51 + return fX * a.fY - fY * a.fX; 1.52 + } 1.53 + 1.54 + double dot(const SkDVector& a) const { 1.55 + return fX * a.fX + fY * a.fY; 1.56 + } 1.57 + 1.58 + double length() const { 1.59 + return sqrt(lengthSquared()); 1.60 + } 1.61 + 1.62 + double lengthSquared() const { 1.63 + return fX * fX + fY * fY; 1.64 + } 1.65 +}; 1.66 + 1.67 +struct SkDPoint { 1.68 + double fX; 1.69 + double fY; 1.70 + 1.71 + void set(const SkPoint& pt) { 1.72 + fX = pt.fX; 1.73 + fY = pt.fY; 1.74 + } 1.75 + 1.76 + friend SkDVector operator-(const SkDPoint& a, const SkDPoint& b); 1.77 + 1.78 + friend bool operator==(const SkDPoint& a, const SkDPoint& b) { 1.79 + return a.fX == b.fX && a.fY == b.fY; 1.80 + } 1.81 + 1.82 + friend bool operator!=(const SkDPoint& a, const SkDPoint& b) { 1.83 + return a.fX != b.fX || a.fY != b.fY; 1.84 + } 1.85 + 1.86 + void operator=(const SkPoint& pt) { 1.87 + fX = pt.fX; 1.88 + fY = pt.fY; 1.89 + } 1.90 + 1.91 + 1.92 + void operator+=(const SkDVector& v) { 1.93 + fX += v.fX; 1.94 + fY += v.fY; 1.95 + } 1.96 + 1.97 + void operator-=(const SkDVector& v) { 1.98 + fX -= v.fX; 1.99 + fY -= v.fY; 1.100 + } 1.101 + 1.102 + // note: this can not be implemented with 1.103 + // return approximately_equal(a.fY, fY) && approximately_equal(a.fX, fX); 1.104 + // because that will not take the magnitude of the values into account 1.105 + bool approximatelyEqual(const SkDPoint& a) const { 1.106 + if (approximately_equal(fX, a.fX) && approximately_equal(fY, a.fY)) { 1.107 + return true; 1.108 + } 1.109 + if (!RoughlyEqualUlps(fX, a.fX) || !RoughlyEqualUlps(fY, a.fY)) { 1.110 + return false; 1.111 + } 1.112 + double dist = distance(a); // OPTIMIZATION: can we compare against distSq instead ? 1.113 + double tiniest = SkTMin(SkTMin(SkTMin(fX, a.fX), fY), a.fY); 1.114 + double largest = SkTMax(SkTMax(SkTMax(fX, a.fX), fY), a.fY); 1.115 + largest = SkTMax(largest, -tiniest); 1.116 + return AlmostBequalUlps(largest, largest + dist); // is the dist within ULPS tolerance? 1.117 + } 1.118 + 1.119 + bool approximatelyEqual(const SkPoint& a) const { 1.120 + SkDPoint dA; 1.121 + dA.set(a); 1.122 + return approximatelyEqual(dA); 1.123 + } 1.124 + 1.125 + static bool ApproximatelyEqual(const SkPoint& a, const SkPoint& b) { 1.126 + if (approximately_equal(a.fX, b.fX) && approximately_equal(a.fY, b.fY)) { 1.127 + return true; 1.128 + } 1.129 + if (!RoughlyEqualUlps(a.fX, b.fX) || !RoughlyEqualUlps(a.fY, b.fY)) { 1.130 + return false; 1.131 + } 1.132 + SkDPoint dA, dB; 1.133 + dA.set(a); 1.134 + dB.set(b); 1.135 + double dist = dA.distance(dB); // OPTIMIZATION: can we compare against distSq instead ? 1.136 + float tiniest = SkTMin(SkTMin(SkTMin(a.fX, b.fX), a.fY), b.fY); 1.137 + float largest = SkTMax(SkTMax(SkTMax(a.fX, b.fX), a.fY), b.fY); 1.138 + largest = SkTMax(largest, -tiniest); 1.139 + return AlmostBequalUlps((double) largest, largest + dist); // is dist within ULPS tolerance? 1.140 + } 1.141 + 1.142 + bool approximatelyPEqual(const SkDPoint& a) const { 1.143 + if (approximately_equal(fX, a.fX) && approximately_equal(fY, a.fY)) { 1.144 + return true; 1.145 + } 1.146 + if (!RoughlyEqualUlps(fX, a.fX) || !RoughlyEqualUlps(fY, a.fY)) { 1.147 + return false; 1.148 + } 1.149 + double dist = distance(a); // OPTIMIZATION: can we compare against distSq instead ? 1.150 + double tiniest = SkTMin(SkTMin(SkTMin(fX, a.fX), fY), a.fY); 1.151 + double largest = SkTMax(SkTMax(SkTMax(fX, a.fX), fY), a.fY); 1.152 + largest = SkTMax(largest, -tiniest); 1.153 + return AlmostPequalUlps(largest, largest + dist); // is the dist within ULPS tolerance? 1.154 + } 1.155 + 1.156 + bool approximatelyZero() const { 1.157 + return approximately_zero(fX) && approximately_zero(fY); 1.158 + } 1.159 + 1.160 + SkPoint asSkPoint() const { 1.161 + SkPoint pt = {SkDoubleToScalar(fX), SkDoubleToScalar(fY)}; 1.162 + return pt; 1.163 + } 1.164 + 1.165 + double distance(const SkDPoint& a) const { 1.166 + SkDVector temp = *this - a; 1.167 + return temp.length(); 1.168 + } 1.169 + 1.170 + double distanceSquared(const SkDPoint& a) const { 1.171 + SkDVector temp = *this - a; 1.172 + return temp.lengthSquared(); 1.173 + } 1.174 + 1.175 + static SkDPoint Mid(const SkDPoint& a, const SkDPoint& b) { 1.176 + SkDPoint result; 1.177 + result.fX = (a.fX + b.fX) / 2; 1.178 + result.fY = (a.fY + b.fY) / 2; 1.179 + return result; 1.180 + } 1.181 + 1.182 + bool moreRoughlyEqual(const SkDPoint& a) const { 1.183 + if (roughly_equal(fX, a.fX) && roughly_equal(fY, a.fY)) { 1.184 + return true; 1.185 + } 1.186 + double dist = distance(a); // OPTIMIZATION: can we compare against distSq instead ? 1.187 + double tiniest = SkTMin(SkTMin(SkTMin(fX, a.fX), fY), a.fY); 1.188 + double largest = SkTMax(SkTMax(SkTMax(fX, a.fX), fY), a.fY); 1.189 + largest = SkTMax(largest, -tiniest); 1.190 + return RoughlyEqualUlps(largest, largest + dist); // is the dist within ULPS tolerance? 1.191 + } 1.192 + 1.193 + bool roughlyEqual(const SkDPoint& a) const { 1.194 + return roughly_equal(a.fY, fY) && roughly_equal(a.fX, fX); 1.195 + } 1.196 + 1.197 + #ifdef SK_DEBUG 1.198 + void dump() { 1.199 + SkDebugf("{"); 1.200 + DebugDumpDouble(fX); 1.201 + SkDebugf(", "); 1.202 + DebugDumpDouble(fY); 1.203 + SkDebugf("}"); 1.204 + } 1.205 + 1.206 + static void dump(const SkPoint& pt) { 1.207 + SkDebugf("{"); 1.208 + DebugDumpFloat(pt.fX); 1.209 + SkDebugf(", "); 1.210 + DebugDumpFloat(pt.fY); 1.211 + SkDebugf("}"); 1.212 + } 1.213 + #endif 1.214 +}; 1.215 + 1.216 +#endif