xref: /third_party/skia/include/core/SkPoint3.h (revision cb93a386)
1/*
2 * Copyright 2015 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
8#ifndef SkPoint3_DEFINED
9#define SkPoint3_DEFINED
10
11#include "include/core/SkPoint.h"
12
13struct SK_API SkPoint3 {
14    SkScalar fX, fY, fZ;
15
16    static SkPoint3 Make(SkScalar x, SkScalar y, SkScalar z) {
17        SkPoint3 pt;
18        pt.set(x, y, z);
19        return pt;
20    }
21
22    /** Writes text representation of SkPoint3 to string.
23
24        @param desc     the string storing a description of parameters.
25        @param depth    the number of tabs preceding each line.
26    */
27    void dump(std::string& desc, int depth) const;
28
29    SkScalar x() const { return fX; }
30    SkScalar y() const { return fY; }
31    SkScalar z() const { return fZ; }
32
33    void set(SkScalar x, SkScalar y, SkScalar z) { fX = x; fY = y; fZ = z; }
34
35    friend bool operator==(const SkPoint3& a, const SkPoint3& b) {
36        return a.fX == b.fX && a.fY == b.fY && a.fZ == b.fZ;
37    }
38
39    friend bool operator!=(const SkPoint3& a, const SkPoint3& b) {
40        return !(a == b);
41    }
42
43    /** Returns the Euclidian distance from (0,0,0) to (x,y,z)
44    */
45    static SkScalar Length(SkScalar x, SkScalar y, SkScalar z);
46
47    /** Return the Euclidian distance from (0,0,0) to the point
48    */
49    SkScalar length() const { return SkPoint3::Length(fX, fY, fZ); }
50
51    /** Set the point (vector) to be unit-length in the same direction as it
52        already points.  If the point has a degenerate length (i.e., nearly 0)
53        then set it to (0,0,0) and return false; otherwise return true.
54    */
55    bool normalize();
56
57    /** Return a new point whose X, Y and Z coordinates are scaled.
58    */
59    SkPoint3 makeScale(SkScalar scale) const {
60        SkPoint3 p;
61        p.set(scale * fX, scale * fY, scale * fZ);
62        return p;
63    }
64
65    /** Scale the point's coordinates by scale.
66    */
67    void scale(SkScalar value) {
68        fX *= value;
69        fY *= value;
70        fZ *= value;
71    }
72
73    /** Return a new point whose X, Y and Z coordinates are the negative of the
74        original point's
75    */
76    SkPoint3 operator-() const {
77        SkPoint3 neg;
78        neg.fX = -fX;
79        neg.fY = -fY;
80        neg.fZ = -fZ;
81        return neg;
82    }
83
84    /** Returns a new point whose coordinates are the difference between
85        a and b (i.e., a - b)
86    */
87    friend SkPoint3 operator-(const SkPoint3& a, const SkPoint3& b) {
88        return { a.fX - b.fX, a.fY - b.fY, a.fZ - b.fZ };
89    }
90
91    /** Returns a new point whose coordinates are the sum of a and b (a + b)
92    */
93    friend SkPoint3 operator+(const SkPoint3& a, const SkPoint3& b) {
94        return { a.fX + b.fX, a.fY + b.fY, a.fZ + b.fZ };
95    }
96
97    /** Add v's coordinates to the point's
98    */
99    void operator+=(const SkPoint3& v) {
100        fX += v.fX;
101        fY += v.fY;
102        fZ += v.fZ;
103    }
104
105    /** Subtract v's coordinates from the point's
106    */
107    void operator-=(const SkPoint3& v) {
108        fX -= v.fX;
109        fY -= v.fY;
110        fZ -= v.fZ;
111    }
112
113    friend SkPoint3 operator*(SkScalar t, SkPoint3 p) {
114        return { t * p.fX, t * p.fY, t * p.fZ };
115    }
116
117    /** Returns true if fX, fY, and fZ are measurable values.
118
119     @return  true for values other than infinities and NaN
120     */
121    bool isFinite() const {
122        SkScalar accum = 0;
123        accum *= fX;
124        accum *= fY;
125        accum *= fZ;
126
127        // accum is either NaN or it is finite (zero).
128        SkASSERT(0 == accum || SkScalarIsNaN(accum));
129
130        // value==value will be true iff value is not NaN
131        // TODO: is it faster to say !accum or accum==accum?
132        return !SkScalarIsNaN(accum);
133    }
134
135    /** Returns the dot product of a and b, treating them as 3D vectors
136    */
137    static SkScalar DotProduct(const SkPoint3& a, const SkPoint3& b) {
138        return a.fX * b.fX + a.fY * b.fY + a.fZ * b.fZ;
139    }
140
141    SkScalar dot(const SkPoint3& vec) const {
142        return DotProduct(*this, vec);
143    }
144
145    /** Returns the cross product of a and b, treating them as 3D vectors
146    */
147    static SkPoint3 CrossProduct(const SkPoint3& a, const SkPoint3& b) {
148        SkPoint3 result;
149        result.fX = a.fY*b.fZ - a.fZ*b.fY;
150        result.fY = a.fZ*b.fX - a.fX*b.fZ;
151        result.fZ = a.fX*b.fY - a.fY*b.fX;
152
153        return result;
154    }
155
156    SkPoint3 cross(const SkPoint3& vec) const {
157        return CrossProduct(*this, vec);
158    }
159};
160
161typedef SkPoint3 SkVector3;
162typedef SkPoint3 SkColor3f;
163
164#endif
165