1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef MOZILLA_BASEPOINT3D_H_
8 #define MOZILLA_BASEPOINT3D_H_
10 #include "mozilla/Assertions.h"
16 * Do not use this class directly. Subclass it, pass that subclass as the
17 * Sub parameter, and only use that subclass. This allows methods to safely
18 * cast 'this' to 'Sub*'.
20 template <class T
, class Sub
>
30 BasePoint3D() : x(0), y(0), z(0) {}
31 BasePoint3D(T aX
, T aY
, T aZ
) : x(aX
), y(aY
), z(aZ
) {}
33 void MoveTo(T aX
, T aY
, T aZ
) {
38 void MoveBy(T aDx
, T aDy
, T aDz
) {
44 // Note that '=' isn't defined so we'll get the
45 // compiler generated default assignment operator
47 T
& operator[](int aIndex
) {
48 MOZ_ASSERT(aIndex
>= 0 && aIndex
<= 2);
49 return *((&x
) + aIndex
);
52 const T
& operator[](int aIndex
) const {
53 MOZ_ASSERT(aIndex
>= 0 && aIndex
<= 2);
54 return *((&x
) + aIndex
);
57 bool operator==(const Sub
& aPoint
) const {
58 return x
== aPoint
.x
&& y
== aPoint
.y
&& z
== aPoint
.z
;
60 bool operator!=(const Sub
& aPoint
) const {
61 return x
!= aPoint
.x
|| y
!= aPoint
.y
|| z
!= aPoint
.z
;
64 Sub
operator+(const Sub
& aPoint
) const {
65 return Sub(x
+ aPoint
.x
, y
+ aPoint
.y
, z
+ aPoint
.z
);
67 Sub
operator-(const Sub
& aPoint
) const {
68 return Sub(x
- aPoint
.x
, y
- aPoint
.y
, z
- aPoint
.z
);
70 Sub
& operator+=(const Sub
& aPoint
) {
74 return *static_cast<Sub
*>(this);
76 Sub
& operator-=(const Sub
& aPoint
) {
80 return *static_cast<Sub
*>(this);
83 Sub
operator*(T aScale
) const {
84 return Sub(x
* aScale
, y
* aScale
, z
* aScale
);
86 Sub
operator/(T aScale
) const {
87 return Sub(x
/ aScale
, y
/ aScale
, z
/ aScale
);
90 Sub
& operator*=(T aScale
) {
94 return *static_cast<Sub
*>(this);
97 Sub
& operator/=(T aScale
) {
101 return *static_cast<Sub
*>(this);
104 Sub
operator-() const { return Sub(-x
, -y
, -z
); }
106 Sub
CrossProduct(const Sub
& aPoint
) const {
107 return Sub(y
* aPoint
.z
- aPoint
.y
* z
, z
* aPoint
.x
- aPoint
.z
* x
,
108 x
* aPoint
.y
- aPoint
.x
* y
);
111 T
DotProduct(const Sub
& aPoint
) const {
112 return x
* aPoint
.x
+ y
* aPoint
.y
+ z
* aPoint
.z
;
115 T
Length() const { return sqrt(x
* x
+ y
* y
+ z
* z
); }
117 // Invalid for points with distance from origin of 0.
118 void Normalize() { *this /= Length(); }
120 void RobustNormalize() {
121 // If the distance is infinite, we scale it by 1/(the maximum value of T)
122 // before doing normalization, so we can avoid getting a zero point.
124 if (mozilla::IsInfinite(length
)) {
125 *this /= std::numeric_limits
<T
>::max();
132 friend std::ostream
& operator<<(std::ostream
& stream
,
133 const BasePoint3D
<T
, Sub
>& aPoint
) {
134 return stream
<< '(' << aPoint
.x
<< ',' << aPoint
.y
<< ',' << aPoint
.z
140 } // namespace mozilla
142 #endif /* MOZILLA_BASEPOINT3D_H_ */