1eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Copyright 2013 The Chromium Authors. All rights reserved.
2eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// found in the LICENSE file.
4eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
5eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#ifndef VECTOR2_H_
6eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#define VECTOR2_H_
7eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
8eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <stdlib.h>
9eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <cmath>
10eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <limits>
11eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// A small class that encapsulates a 2D vector.  Provides a few simple
13eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// operations.
14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
15eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochclass Vector2 {
16eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch public:
17eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Vector2() : x_(0.0), y_(0.0) {}
18eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Vector2(double x, double y) : x_(x), y_(y) {}
19eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ~Vector2() {}
20eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
21eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Create a new vector that represents a - b.
22eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  static Vector2 Difference(const Vector2& a, const Vector2& b) {
23eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    Vector2 diff(a.x() - b.x(), a.y() - b.y());
24eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return diff;
25eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
26eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
27eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // The magnitude of this vector.
28eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  double Magnitude() const {
29eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return sqrt(x_ * x_ + y_ * y_);
30eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
31eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
32eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Add |vec| to this vector.  Works in-place.
33eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  void Add(const Vector2& vec) {
34eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    x_ += vec.x();
35eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    y_ += vec.y();
36eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
37eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
38eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Normalize this vector in-place.  If the vector is degenerate (size 0)
39eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // then do nothing.
40eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  void Normalize() {
41eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    double mag = Magnitude();
42eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (fabs(mag) < std::numeric_limits<double>::epsilon())
43eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      return;
44eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    Scale(1.0 / mag);
45eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
46eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
47eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Scale the vector in-place by |scale|.
48eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  void Scale(double scale) {
49eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    x_ *= scale;
50eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    y_ *= scale;
51eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
52eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
53eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Clamp a vector to a maximum magnitude.  Works on the vector in-place.
54eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // @param max_mag The maximum magnitude of the vector.
55eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  void Clamp(double max_mag) {
56eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    double mag = Magnitude();
57eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (mag > max_mag) {
58eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      Scale(max_mag / mag);  // Does Normalize() followed by Scale(max_mag).
59eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    }
60eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
61eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
62eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Compute the "heading" of a vector - this is the angle in radians between
63eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // the vector and the x-axis.
64eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // @return {!number} The "heading" angle in radians.
65eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  double Heading() const {
66eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    double angle = atan2(y_, x_);
67eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return angle;
68eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
69eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
70eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Accessors and mutators for the coordinate values.
71eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  double x() const { return x_; }
72eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  void set_x(double x) { x_ = x; }
73eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
74eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  double y() const { return y_; }
75eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  void set_y(double y) { y_ = y; }
76eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
77eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  double x_;
78eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  double y_;
79eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch};
80eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
81eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif  // VECTOR2_H_
82