summaryrefslogtreecommitdiff
path: root/pathops/SkPathOpsPoint.h
diff options
context:
space:
mode:
Diffstat (limited to 'pathops/SkPathOpsPoint.h')
-rw-r--r--pathops/SkPathOpsPoint.h164
1 files changed, 164 insertions, 0 deletions
diff --git a/pathops/SkPathOpsPoint.h b/pathops/SkPathOpsPoint.h
new file mode 100644
index 00000000..045b1b4d
--- /dev/null
+++ b/pathops/SkPathOpsPoint.h
@@ -0,0 +1,164 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#ifndef SkPathOpsPoint_DEFINED
+#define SkPathOpsPoint_DEFINED
+
+#include "SkPathOpsTypes.h"
+#include "SkPoint.h"
+
+inline bool AlmostEqualUlps(const SkPoint& pt1, const SkPoint& pt2) {
+ return AlmostEqualUlps(pt1.fX, pt2.fX) && AlmostEqualUlps(pt1.fY, pt2.fY);
+}
+
+struct SkDVector {
+ double fX, fY;
+
+ friend SkDPoint operator+(const SkDPoint& a, const SkDVector& b);
+
+ void operator+=(const SkDVector& v) {
+ fX += v.fX;
+ fY += v.fY;
+ }
+
+ void operator-=(const SkDVector& v) {
+ fX -= v.fX;
+ fY -= v.fY;
+ }
+
+ void operator/=(const double s) {
+ fX /= s;
+ fY /= s;
+ }
+
+ void operator*=(const double s) {
+ fX *= s;
+ fY *= s;
+ }
+
+ SkVector asSkVector() const {
+ SkVector v = {SkDoubleToScalar(fX), SkDoubleToScalar(fY)};
+ return v;
+ }
+
+ double cross(const SkDVector& a) const {
+ return fX * a.fY - fY * a.fX;
+ }
+
+ double dot(const SkDVector& a) const {
+ return fX * a.fX + fY * a.fY;
+ }
+
+ double length() const {
+ return sqrt(lengthSquared());
+ }
+
+ double lengthSquared() const {
+ return fX * fX + fY * fY;
+ }
+};
+
+struct SkDPoint {
+ double fX;
+ double fY;
+
+ void set(const SkPoint& pt) {
+ fX = pt.fX;
+ fY = pt.fY;
+ }
+
+ friend SkDVector operator-(const SkDPoint& a, const SkDPoint& b);
+
+ friend bool operator==(const SkDPoint& a, const SkDPoint& b) {
+ return a.fX == b.fX && a.fY == b.fY;
+ }
+
+ friend bool operator!=(const SkDPoint& a, const SkDPoint& b) {
+ return a.fX != b.fX || a.fY != b.fY;
+ }
+
+ void operator=(const SkPoint& pt) {
+ fX = pt.fX;
+ fY = pt.fY;
+ }
+
+
+ void operator+=(const SkDVector& v) {
+ fX += v.fX;
+ fY += v.fY;
+ }
+
+ void operator-=(const SkDVector& v) {
+ fX -= v.fX;
+ fY -= v.fY;
+ }
+
+ // note: this can not be implemented with
+ // return approximately_equal(a.fY, fY) && approximately_equal(a.fX, fX);
+ // because that will not take the magnitude of the values
+ bool approximatelyEqual(const SkDPoint& a) const {
+ double denom = SkTMax(fabs(fX), SkTMax(fabs(fY),
+ SkTMax(fabs(a.fX), fabs(a.fY))));
+ if (precisely_zero(denom)) {
+ return true;
+ }
+ double inv = 1 / denom;
+ return approximately_equal(fX * inv, a.fX * inv)
+ && approximately_equal(fY * inv, a.fY * inv);
+ }
+
+ bool approximatelyEqual(const SkPoint& a) const {
+ return AlmostEqualUlps(SkDoubleToScalar(fX), a.fX)
+ && AlmostEqualUlps(SkDoubleToScalar(fY), a.fY);
+ }
+
+ bool approximatelyEqualHalf(const SkDPoint& a) const {
+ double denom = SkTMax(fabs(fX), SkTMax(fabs(fY),
+ SkTMax(fabs(a.fX), fabs(a.fY))));
+ if (denom == 0) {
+ return true;
+ }
+ double inv = 1 / denom;
+ return approximately_equal_half(fX * inv, a.fX * inv)
+ && approximately_equal_half(fY * inv, a.fY * inv);
+ }
+
+ bool approximatelyZero() const {
+ return approximately_zero(fX) && approximately_zero(fY);
+ }
+
+ SkPoint asSkPoint() const {
+ SkPoint pt = {SkDoubleToScalar(fX), SkDoubleToScalar(fY)};
+ return pt;
+ }
+
+ double distance(const SkDPoint& a) const {
+ SkDVector temp = *this - a;
+ return temp.length();
+ }
+
+ double distanceSquared(const SkDPoint& a) const {
+ SkDVector temp = *this - a;
+ return temp.lengthSquared();
+ }
+
+ static SkDPoint Mid(const SkDPoint& a, const SkDPoint& b) {
+ SkDPoint result;
+ result.fX = (a.fX + b.fX) / 2;
+ result.fY = (a.fY + b.fY) / 2;
+ return result;
+ }
+
+ double moreRoughlyEqual(const SkDPoint& a) const {
+ return more_roughly_equal(a.fY, fY) && more_roughly_equal(a.fX, fX);
+ }
+
+ double roughlyEqual(const SkDPoint& a) const {
+ return roughly_equal(a.fY, fY) && roughly_equal(a.fX, fX);
+ }
+};
+
+#endif