Ion: math/vector.h Source File

1 

18 #ifndef ION_MATH_VECTOR_H_

19 #define ION_MATH_VECTOR_H_

20 

26 

27 #include "base/integral_types.h"

31 

32 namespace ion {

33 namespace math {

34 

36 

39 

40 

42 template <int Dimension, typename T>

44  public:

48 

50  void Set(T e0);

51  void Set(T e0, T e1);

52  void Set(T e0, T e1, T e2);

53  void Set(T e0, T e1, T e2, T e3);

54 

61  DCHECK(index >= 0 && index < Dimension);

62  return elem_[index];

63  }

64 

71  DCHECK(index >= 0 && index < Dimension);

72  return elem_[index];

73  }

74 

77 

79  T* Data() { return &elem_[0]; }

80  const T* Data() const { return &elem_[0]; }

81 

83  void Print(std::ostream& out, const char tag) const {

84  out << tag << "[";

85  for (int i = 0; i < Dimension; ++i) {

86  out << elem_[i];

87  if (i != Dimension - 1)

88  out << ", ";

89  }

90  out << "]";

91  }

92 

94  template <char tag>

95  void Read(std::istream& in) {

98  for (int i = 0; i < Dimension; ++i) {

99  in >> v.elem_[i];

100  if (i != Dimension - 1 && !base::GetExpectedChar<','>(in))

101  return;

102  }

104  *this = v;

105  }

106  }

107 

108  protected:

111 

112  explicit VectorBase(T e0);

113  VectorBase(T e0, T e1);

114  VectorBase(T e0, T e1, T e2);

115  VectorBase(T e0, T e1, T e2, T e3);

116 

121 

125 

128 

131 

136 

145 

148 

162 

166 

167  private:

169  T elem_[Dimension];

170 };

171 

173 

176 

177 

179 template <int Dimension, typename T>

181  public:

184 

190 

194 

199 

202 

205 

214 

220 

223 

227  }

230  }

233  }

237  }

240  }

243  }

246  }

248  return Vector(s / v[0], s / v[1], s / v[2]);

249  }

250 

254  }

257  }

258 

259  private:

262 

264  static const Vector ToVector(const BaseType& b) {

267  return static_cast<const Vector&>(b);

268  }

269 

271  template<int D, typename U> friend class Point;

272 };

273 

275 template <int Dimension, typename T>

276 std::ostream& operator<<(std::ostream& out, const Vector<Dimension, T>& v) {

277  v.Print(out, 'V');

278  return out;

279 }

280 

282 template <int Dimension, typename T>

284  v. template Read<'V'>(in);

285  return in;

286 }

287 

289 

292 

293 

295 template <int Dimension, typename T>

297  public:

300 

303 

309 

313 

318 

320  static const Point Zero() { return ToPoint(BaseType::Zero()); }

321 

323  static const Point Fill(T value) { return ToPoint(BaseType::Fill(value)); }

324 

327  void operator+=(const VectorType& v) { BaseType::Add(v); }

328  void operator-=(const VectorType& v) { BaseType::Subtract(v); }

331 

333  const Point operator-() const { return ToPoint(BaseType::Negation()); }

334 

337  return ToPoint(BaseType::Sum(p0, p1));

338  }

341  return ToPoint(BaseType::Sum(p, v));

342  }

344  return ToPoint(BaseType::Sum(p, v));

345  }

346 

349  return ToPoint(BaseType::Difference(p, v));

350  }

353  return ToVector(BaseType::Difference(p0, p1));

354  }

355 

358  return ToPoint(BaseType::Scale(p, s));

359  }

362  return ToPoint(BaseType::Scale(p, s));

363  }

365  return ToPoint(BaseType::Product(v, s));

366  }

368  return ToPoint(BaseType::Quotient(v, s));

369  }

371  return ToPoint(BaseType::Divide(p, s));

372  }

373 

376  return BaseType::AreValuesEqual(p0, p1);

377  }

379  return !BaseType::AreValuesEqual(p0, p1);

380  }

381 

382  private:

385 

387  static const Point ToPoint(const BaseType& b) {

390  return *static_cast<const Point*>(&b);

391  }

393  static const VectorType ToVector(const BaseType& b) {

394  return VectorType::ToVector(b);

395  }

396 };

397 

399 template <int Dimension, typename T>

400 std::ostream& operator<<(std::ostream& out, const Point<Dimension, T>& p) {

401  p.Print(out, 'P');

402  return out;

403 }

404 

406 template <int Dimension, typename T>

408  v. template Read<'P'>(in);

409  return in;

410 }

411 

413 

416 

417 

418 template <int Dimension, typename T>

420  ION_STATIC_ASSERT(Dimension == 1, "Bad Dimension in VectorBase constructor");

421  elem_[0] = e0;

422 }

423 

424 template <int Dimension, typename T>

426  ION_STATIC_ASSERT(Dimension == 2, "Bad Dimension in VectorBase constructor");

427  elem_[0] = e0;

428  elem_[1] = e1;

429 }

430 

431 template <int Dimension, typename T>

433  ION_STATIC_ASSERT(Dimension == 3, "Bad Dimension in VectorBase constructor");

434  elem_[0] = e0;

435  elem_[1] = e1;

436  elem_[2] = e2;

437 }

438 

439 template <int Dimension, typename T>

441  ION_STATIC_ASSERT(Dimension == 4, "Bad Dimension in VectorBase constructor");

442  elem_[0] = e0;

443  elem_[1] = e1;

444  elem_[2] = e2;

445  elem_[3] = e3;

446 }

447 

448 template <int Dimension, typename T>

450  T s) {

451  ION_STATIC_ASSERT(Dimension >= 2, "Bad Dimension in VectorBase constructor");

452  for (int i = 0; i < Dimension - 1; ++i)

453  elem_[i] = v[i];

454  elem_[Dimension - 1] = s;

455 }

456 

457 template <int Dimension, typename T> template <typename U>

459  for (int i = 0; i < Dimension; ++i)

460  elem_[i] = static_cast<T>(v[i]);

461 }

462 

463 template <int Dimension, typename T>

465  ION_STATIC_ASSERT(Dimension == 1, "Bad Dimension in VectorBase::Set");

466  elem_[0] = e0;

467 }

468 

469 template <int Dimension, typename T>

471  ION_STATIC_ASSERT(Dimension == 2, "Bad Dimension in VectorBase::Set");

472  elem_[0] = e0;

473  elem_[1] = e1;

474 }

475 

476 template <int Dimension, typename T>

478  ION_STATIC_ASSERT(Dimension == 3, "Bad Dimension in VectorBase::Set");

479  elem_[0] = e0;

480  elem_[1] = e1;

481  elem_[2] = e2;

482 }

483 

484 template <int Dimension, typename T>

486  ION_STATIC_ASSERT(Dimension == 4, "Bad Dimension in VectorBase::Set");

487  elem_[0] = e0;

488  elem_[1] = e1;

489  elem_[2] = e2;

490  elem_[3] = e3;

491 }

492 

494 template <int Dimension, typename T>

495 template <typename U>

499  static const Vector AxisX() {

500  return Vector(static_cast<U>(1));

501  }

502  static const VectorBase Fill(U value) { return VectorBase(value); }

503 };

504 

505 template <int Dimension, typename T>

506 template <typename U>

511  return Vector(static_cast<U>(1), static_cast<U>(0));

512  }

514  return Vector(static_cast<U>(0), static_cast<U>(1));

515  }

517 };

518 

519 template <int Dimension, typename T>

520 template <typename U>

525  return Vector(static_cast<U>(1), static_cast<U>(0), static_cast<U>(0));

526  }

528  return Vector(static_cast<U>(0), static_cast<U>(1), static_cast<U>(0));

529  }

531  return Vector(static_cast<U>(0), static_cast<U>(0), static_cast<U>(1));

532  }

534  return VectorBase(value, value, value);

535  }

536 };

537 

538 template <int Dimension, typename T>

539 template <typename U>

544  return Vector(static_cast<U>(1), static_cast<U>(0), static_cast<U>(0),

545  static_cast<U>(0));

546  }

548  return Vector(static_cast<U>(0), static_cast<U>(1), static_cast<U>(0),

549  static_cast<U>(0));

550  }

552  return Vector(static_cast<U>(0), static_cast<U>(0), static_cast<U>(1),

553  static_cast<U>(0));

554  }

556  return Vector(static_cast<U>(0), static_cast<U>(0), static_cast<U>(0),

557  static_cast<U>(1));

558  }

560  return VectorBase(value, value, value, value);

561  }

562 };

563 

565 template <int Dimension, typename T>

569  return v;

570 }

571 

572 template <int Dimension, typename T>

575 }

576 

577 template <int Dimension, typename T>

581  return v;

582 }

583 

584 template <int Dimension, typename T>

588  return v;

589 }

590 

591 template <int Dimension, typename T>

595  return v;

596 }

597 

598 template <int Dimension, typename T>

602  return v;

603 }

604 

605 template <int Dimension, typename T>

607  for (int i = 0; i < Dimension; ++i)

608  elem_[i] = static_cast<T>(elem_[i] + v.elem_[i]);

609 }

610 

611 template <int Dimension, typename T>

613  for (int i = 0; i < Dimension; ++i)

614  elem_[i] = static_cast<T>(elem_[i] - v.elem_[i]);

615 }

616 

617 template <int Dimension, typename T>

619  for (int i = 0; i < Dimension; ++i)

620  elem_[i] = static_cast<T>(elem_[i] * s);

621 }

622 

623 template <int Dimension, typename T>

627  for (int i = 0; i < Dimension; ++i)

628  elem_[i] = static_cast<T>(elem_[i] / s);

629 }

630 

631 template <int Dimension, typename T>

634  for (int i = 0; i < Dimension; ++i)

635  result.elem_[i] = static_cast<T>(-elem_[i]);

636  return result;

637 }

638 

639 template <int Dimension, typename T>

643  for (int i = 0; i < Dimension; ++i)

644  result.elem_[i] = static_cast<T>(v0.elem_[i] * v1.elem_[i]);

645  return result;

646 }

647 

648 template <int Dimension, typename T>

652  for (int i = 0; i < Dimension; ++i)

653  result.elem_[i] = static_cast<T>(v0.elem_[i] / v1.elem_[i]);

654  return result;

655 }

656 

657 template <int Dimension, typename T>

661  for (int i = 0; i < Dimension; ++i)

662  result.elem_[i] = static_cast<T>(v0.elem_[i] + v1.elem_[i]);

663  return result;

664 }

665 

666 template <int Dimension, typename T>

670  for (int i = 0; i < Dimension; ++i)

671  result.elem_[i] = static_cast<T>(v0.elem_[i] - v1.elem_[i]);

672  return result;

673 }

674 

675 template <int Dimension, typename T>

679  for (int i = 0; i < Dimension; ++i)

680  result.elem_[i] = static_cast<T>(v.elem_[i] * s);

681  return result;

682 }

683 

684 template <int Dimension, typename T>

688  for (int i = 0; i < Dimension; ++i)

689  result.elem_[i] = static_cast<T>(v.elem_[i] / s);

690  return result;

691 }

692 

693 template <int Dimension, typename T>

696  for (int i = 0; i < Dimension; ++i) {

697  if (v0.elem_[i] != v1.elem_[i])

698  return false;

699  }

700  return true;

701 }

702 

704 

707 

708 

709 #define ION_INSTANTIATE_VECTOR_TYPE(type) \

710 typedef type<1, int8> type ## 1i8; \

711 typedef type<1, uint8> type ## 1ui8; \

712 typedef type<1, int16> type ## 1i16; \

713 typedef type<1, uint16> type ## 1ui16; \

714 typedef type<1, int32> type ## 1i; \

715 typedef type<1, uint32> type ## 1ui; \

716 typedef type<1, float> type ## 1f; \

717 typedef type<1, double> type ## 1d; \

718 typedef type<2, int8> type ## 2i8; \

719 typedef type<2, uint8> type ## 2ui8; \

720 typedef type<2, int16> type ## 2i16; \

721 typedef type<2, uint16> type ## 2ui16; \

722 typedef type<2, int32> type ## 2i; \

723 typedef type<2, uint32> type ## 2ui; \

724 typedef type<2, float> type ## 2f; \

725 typedef type<2, double> type ## 2d; \

726 typedef type<3, int8> type ## 3i8; \

727 typedef type<3, uint8> type ## 3ui8; \

728 typedef type<3, int16> type ## 3i16; \

729 typedef type<3, uint16> type ## 3ui16; \

730 typedef type<3, int32> type ## 3i; \

731 typedef type<3, uint32> type ## 3ui; \

732 typedef type<3, float> type ## 3f; \

733 typedef type<3, double> type ## 3d; \

734 typedef type<4, int8> type ## 4i8; \

735 typedef type<4, uint8> type ## 4ui8; \

736 typedef type<4, int16> type ## 4i16; \

737 typedef type<4, uint16> type ## 4ui16; \

738 typedef type<4, int32> type ## 4i; \

739 typedef type<4, uint32> type ## 4ui; \

740 typedef type<4, float> type ## 4f; \

741 typedef type<4, double> type ## 4d

742 

746 

747 #undef ION_INSTANTIATE_VECTOR_TYPE

748 

749 }

750 }

751 

752 #endif // ION_MATH_VECTOR_H_

static const Vector AxisZ()

friend const Vector operator/(T s, const Vector &v)

friend const Vector operator+(const Vector &v0, const Vector &v1)

Binary operators.

Vector(T e0, T e1, T e2, T e3)

friend const Point operator-(const Point &p, const VectorType &v)

Subtracting a Vector from a Point produces another Point.

static const VectorBase Fill(U value)

static bool AreValuesEqual(const VectorBase &v0, const VectorBase &v1)

Returns true if all values in two instances are equal.

const Vector operator-() const

Unary negation operator.

void operator-=(const VectorType &v)

friend bool operator!=(const Point &p0, const Point &p1)

T * Data()

Returns a pointer to the data for interfacing with other libraries.

friend bool operator==(const Point &p0, const Point &p1)

Exact equality and inequality comparisons.

Vector(const Vector< Dimension-1, T > &v, T s)

Constructor for a Vector of dimension N from a Vector of dimension N-1 and a scalar of the correct ty...

friend const Point operator/(const Point &p, T s)

math::Vector< 4, U > Vector

const T & operator[](int index) const

Read-only element accessor.

static const VectorBase Fill(U value)

Point()

The default constructor zero-intializes all elements.

void Print(std::ostream &out, const char tag) const

This is used for printing Vectors and Points to a stream.

static const Vector Zero()

Returns a Vector containing all zeroes.

friend bool operator!=(const Vector &v0, const Vector &v1)

static const VectorBase Fill(U value)

const VectorBase Negation() const

Unary negation.

Point(T e0)

Dimension-specific constructors that are passed individual element values.

math::Vector< 1, U > Vector

friend const Vector operator*(const Vector &v, const Vector &s)

static const Vector AxisX()

friend const Point operator+(const Point &p0, const Point &p1)

Adding two Points produces another Point.

static const Vector AxisW()

Returns a Vector representing the W axis if it exists.

void Read(std::istream &in)

This is used for reading Vectors and Points from a stream.

static const Vector AxisW()

math::Vector< 3, U > Vector

static const Vector Fill(T value)

Returns a Vector with all elements set to the given value.

static const Vector AxisZ()

Returns a Vector representing the Z axis if it exists.

math::VectorBase< 1, U > VectorBase

friend const VectorType operator-(const Point &p0, const Point &p1)

Subtracting two Points results in a Vector.

friend bool operator==(const Vector &v0, const Vector &v1)

Exact equality and inequality comparisons.

Vector()

The default constructor zero-initializes all elements.

math::Vector< 2, U > Vector

Vector(const Vector< Dimension, U > &v)

Copy constructor from a Vector of the same Dimension and any value type that is compatible (via stati...

void Set(T e0)

Sets the vector values.

friend const Vector operator-(const Vector &v0, const Vector &v1)

static const VectorBase Fill(T value)

Returns an instance with all elements set to the given value.

friend const Point operator/(const Point &v, const Point &s)

void Subtract(const VectorBase &v)

Self-modifying subtraction.

static const Vector AxisX()

Point(const Point< Dimension, U > &p)

Copy constructor from a Point of the same Dimension and any value type that is compatible (via static...

Vector(T e0)

Dimension-specific constructors that are passed individual element values.

void operator+=(const Vector &v)

Self-modifying operators.

void operator+=(const Point &v)

Self-modifying operators.

Helper struct to aid in Zero, Fill, and Axis functions.

friend const Point operator+(const VectorType &v, const Point &p)

friend const Vector operator/(const Vector &v, T s)

math::VectorBase< 3, U > VectorBase

std::istream & GetExpectedChar(std::istream &in)

Reads a single character from the stream and returns the stream.

const Point operator-() const

Unary operators.

void Add(const VectorBase &v)

Derived classes use these protected functions to implement type-safe functions and operators...

friend const Vector operator*(T s, const Vector &v)

Copyright 2016 Google Inc.

static const Vector AxisY()

Returns a Vector representing the Y axis if it exists.

Point(T e0, T e1, T e2, T e3)

friend const Point operator*(const Point &p, T s)

Binary scale and division operators.

static const Vector AxisZ()

static const VectorBase Quotient(const VectorBase &v0, const VectorBase &v1)

Binary component-wise division.

static const Vector AxisY()

math::VectorBase< 4, U > VectorBase

static const VectorBase Scale(const VectorBase &v, T s)

Binary multiplication by a scalar.

Point(const Point< Dimension-1, T > &p, T s)

Constructor for a Point of dimension N from a Point of dimension N-1 and a scalar of the correct type...

static const VectorBase Difference(const VectorBase &v0, const VectorBase &v1)

Binary component-wise subtraction.

friend const Point operator*(T s, const Point &p)

static const Vector AxisY()

static const Point Fill(T value)

Returns a Point with all elements set to the given value.

static const VectorBase Product(const VectorBase &v0, const VectorBase &v1)

Binary component-wise multiplication.

VectorBase()

The default constructor zero-initializes all elements.

static const Vector AxisY()

void operator-=(const Vector &v)

static const Point Zero()

Returns a Point containing all zeroes.

math::VectorBase< 2, U > VectorBase

friend const Point operator*(const Point &v, const Point &s)

void operator+=(const VectorType &v)

#define ION_STATIC_ASSERT(expr, message)

Copyright 2016 Google Inc.

static const VectorBase Sum(const VectorBase &v0, const VectorBase &v1)

Binary component-wise addition.

std::istream & operator>>(std::istream &in, Angle< T > &a)

Vector< Dimension, T > VectorType

Convenience typedef for the corresponding Vector type.

ION_INSTANTIATE_VECTOR_TYPE(VectorBase)

T & operator[](int index)

Mutable element accessor.

friend const Point operator+(const Point &p, const VectorType &v)

Adding a Vector to a Point produces another Point.

static const Vector AxisX()

Returns a Vector representing the X axis.

static const Vector AxisX()

static const VectorBase Fill(U value)

void Divide(T s)

Self-modifying division by a scalar.

friend const Vector operator*(const Vector &v, T s)

void Multiply(T s)

Self-modifying multiplication by a scalar.

static const VectorBase Zero()

Returns an instance containing all zeroes.

friend const Vector operator/(const Vector &v, const Vector &s)

static const Vector AxisX()