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