SkPathOpsPoint.h revision 07e97fccd2d85076cd22ef411b0773ab92a18abe
1/* 2 * Copyright 2012 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7#ifndef SkPathOpsPoint_DEFINED 8#define SkPathOpsPoint_DEFINED 9 10#include "SkPathOpsTypes.h" 11#include "SkPoint.h" 12 13inline bool AlmostEqualUlps(const SkPoint& pt1, const SkPoint& pt2) { 14 return AlmostEqualUlps(pt1.fX, pt2.fX) && AlmostEqualUlps(pt1.fY, pt2.fY); 15} 16 17struct SkDVector { 18 double fX, fY; 19 20 friend SkDPoint operator+(const SkDPoint& a, const SkDVector& b); 21 22 void operator+=(const SkDVector& v) { 23 fX += v.fX; 24 fY += v.fY; 25 } 26 27 void operator-=(const SkDVector& v) { 28 fX -= v.fX; 29 fY -= v.fY; 30 } 31 32 void operator/=(const double s) { 33 fX /= s; 34 fY /= s; 35 } 36 37 void operator*=(const double s) { 38 fX *= s; 39 fY *= s; 40 } 41 42 SkVector asSkVector() const { 43 SkVector v = {SkDoubleToScalar(fX), SkDoubleToScalar(fY)}; 44 return v; 45 } 46 47 double cross(const SkDVector& a) const { 48 return fX * a.fY - fY * a.fX; 49 } 50 51 double dot(const SkDVector& a) const { 52 return fX * a.fX + fY * a.fY; 53 } 54 55 double length() const { 56 return sqrt(lengthSquared()); 57 } 58 59 double lengthSquared() const { 60 return fX * fX + fY * fY; 61 } 62}; 63 64struct SkDPoint { 65 double fX; 66 double fY; 67 68 void set(const SkPoint& pt) { 69 fX = pt.fX; 70 fY = pt.fY; 71 } 72 73 friend SkDVector operator-(const SkDPoint& a, const SkDPoint& b); 74 75 friend bool operator==(const SkDPoint& a, const SkDPoint& b) { 76 return a.fX == b.fX && a.fY == b.fY; 77 } 78 79 friend bool operator!=(const SkDPoint& a, const SkDPoint& b) { 80 return a.fX != b.fX || a.fY != b.fY; 81 } 82 83 void operator=(const SkPoint& pt) { 84 fX = pt.fX; 85 fY = pt.fY; 86 } 87 88 89 void operator+=(const SkDVector& v) { 90 fX += v.fX; 91 fY += v.fY; 92 } 93 94 void operator-=(const SkDVector& v) { 95 fX -= v.fX; 96 fY -= v.fY; 97 } 98 99 // note: this can not be implemented with 100 // return approximately_equal(a.fY, fY) && approximately_equal(a.fX, fX); 101 // because that will not take the magnitude of the values 102 bool approximatelyEqual(const SkDPoint& a) const { 103 double denom = SkTMax(fabs(fX), SkTMax(fabs(fY), 104 SkTMax(fabs(a.fX), fabs(a.fY)))); 105 if (denom == 0) { 106 return true; 107 } 108 double inv = 1 / denom; 109 return approximately_equal(fX * inv, a.fX * inv) 110 && approximately_equal(fY * inv, a.fY * inv); 111 } 112 113 bool approximatelyEqual(const SkPoint& a) const { 114 return AlmostEqualUlps(SkDoubleToScalar(fX), a.fX) 115 && AlmostEqualUlps(SkDoubleToScalar(fY), a.fY); 116 } 117 118 bool approximatelyEqualHalf(const SkDPoint& a) const { 119 double denom = SkTMax(fabs(fX), SkTMax(fabs(fY), 120 SkTMax(fabs(a.fX), fabs(a.fY)))); 121 if (denom == 0) { 122 return true; 123 } 124 double inv = 1 / denom; 125 return approximately_equal_half(fX * inv, a.fX * inv) 126 && approximately_equal_half(fY * inv, a.fY * inv); 127 } 128 129 bool approximatelyZero() const { 130 return approximately_zero(fX) && approximately_zero(fY); 131 } 132 133 SkPoint asSkPoint() const { 134 SkPoint pt = {SkDoubleToScalar(fX), SkDoubleToScalar(fY)}; 135 return pt; 136 } 137 138 double distance(const SkDPoint& a) const { 139 SkDVector temp = *this - a; 140 return temp.length(); 141 } 142 143 double distanceSquared(const SkDPoint& a) const { 144 SkDVector temp = *this - a; 145 return temp.lengthSquared(); 146 } 147 148 static SkDPoint Mid(const SkDPoint& a, const SkDPoint& b) { 149 SkDPoint result; 150 result.fX = (a.fX + b.fX) / 2; 151 result.fY = (a.fY + b.fY) / 2; 152 return result; 153 } 154 155 double moreRoughlyEqual(const SkDPoint& a) const { 156 return more_roughly_equal(a.fY, fY) && more_roughly_equal(a.fX, fX); 157 } 158 159 double roughlyEqual(const SkDPoint& a) const { 160 return roughly_equal(a.fY, fY) && roughly_equal(a.fX, fX); 161 } 162}; 163 164#endif 165