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_BASEPOINT4D_H_
8 #define MOZILLA_BASEPOINT4D_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 BasePoint4D() : x(0), y(0), z(0), w(0) {}
31 BasePoint4D(T aX
, T aY
, T aZ
, T aW
) : x(aX
), y(aY
), z(aZ
), w(aW
) {}
33 void MoveTo(T aX
, T aY
, T aZ
, T aW
) {
39 void MoveBy(T aDx
, T aDy
, T aDz
, T aDw
) {
46 // Note that '=' isn't defined so we'll get the
47 // compiler generated default assignment operator
49 bool operator==(const Sub
& aPoint
) const {
50 return x
== aPoint
.x
&& y
== aPoint
.y
&& z
== aPoint
.z
&& w
== aPoint
.w
;
52 bool operator!=(const Sub
& aPoint
) const {
53 return x
!= aPoint
.x
|| y
!= aPoint
.y
|| z
!= aPoint
.z
|| w
!= aPoint
.w
;
56 Sub
operator+(const Sub
& aPoint
) const {
57 return Sub(x
+ aPoint
.x
, y
+ aPoint
.y
, z
+ aPoint
.z
, w
+ aPoint
.w
);
59 Sub
operator-(const Sub
& aPoint
) const {
60 return Sub(x
- aPoint
.x
, y
- aPoint
.y
, z
- aPoint
.z
, w
- aPoint
.w
);
62 Sub
& operator+=(const Sub
& aPoint
) {
67 return *static_cast<Sub
*>(this);
69 Sub
& operator-=(const Sub
& aPoint
) {
74 return *static_cast<Sub
*>(this);
77 Sub
operator*(T aScale
) const {
78 return Sub(x
* aScale
, y
* aScale
, z
* aScale
, w
* aScale
);
80 Sub
operator/(T aScale
) const {
81 return Sub(x
/ aScale
, y
/ aScale
, z
/ aScale
, w
/ aScale
);
84 Sub
& operator*=(T aScale
) {
89 return *static_cast<Sub
*>(this);
92 Sub
& operator/=(T aScale
) {
97 return *static_cast<Sub
*>(this);
100 Sub
operator-() const { return Sub(-x
, -y
, -z
, -w
); }
102 T
& operator[](int aIndex
) {
103 MOZ_ASSERT(aIndex
>= 0 && aIndex
<= 3, "Invalid array index");
104 return *((&x
) + aIndex
);
107 const T
& operator[](int aIndex
) const {
108 MOZ_ASSERT(aIndex
>= 0 && aIndex
<= 3, "Invalid array index");
109 return *((&x
) + aIndex
);
112 T
DotProduct(const Sub
& aPoint
) const {
113 return x
* aPoint
.x
+ y
* aPoint
.y
+ z
* aPoint
.z
+ w
* aPoint
.w
;
116 // Ignores the 4th component!
117 Sub
CrossProduct(const Sub
& aPoint
) const {
118 return Sub(y
* aPoint
.z
- aPoint
.y
* z
, z
* aPoint
.x
- aPoint
.z
* x
,
119 x
* aPoint
.y
- aPoint
.x
* y
, 0);
122 T
Length() const { return sqrt(x
* x
+ y
* y
+ z
* z
+ w
* w
); }
124 void Normalize() { *this /= Length(); }
126 bool HasPositiveWCoord() { return w
> 0; }
130 } // namespace mozilla
132 #endif /* MOZILLA_BASEPOINT4D_H_ */