|
@@ -1,289 +0,0 @@
|
|
|
-/****************************************
|
|
|
-* Class: 2D vector class
|
|
|
-* Purpose: A single header file handling 2D vector computations.
|
|
|
-* Author: Zhao Liang
|
|
|
-* Last Updated: 2021/01/20
|
|
|
-*****************************************
|
|
|
-*
|
|
|
-* Note: Need to add error handling procedures in divisions.
|
|
|
-*
|
|
|
-*/
|
|
|
-
|
|
|
-#ifndef VEC2_H
|
|
|
-#define VEC2_H
|
|
|
-
|
|
|
-#pragma once
|
|
|
-
|
|
|
-#include <cmath>
|
|
|
-#include <iostream>
|
|
|
-
|
|
|
-namespace iv {
|
|
|
-namespace math {
|
|
|
-
|
|
|
-constexpr double _EPSILON = 1e-12;
|
|
|
-
|
|
|
-class Vec2
|
|
|
-{
|
|
|
-public:
|
|
|
-
|
|
|
- // ----------------------------------------
|
|
|
-
|
|
|
- /*
|
|
|
- * Constructors.
|
|
|
- */
|
|
|
-
|
|
|
- Vec2() : x_(0), y_(0) {}
|
|
|
-
|
|
|
- explicit Vec2(double a) : x_(a), y_(a) {}
|
|
|
-
|
|
|
- Vec2(double a, double b) : x_(a), y_(b) {}
|
|
|
-
|
|
|
- // ----------------------------------------
|
|
|
-
|
|
|
- // Compare to another vector
|
|
|
- bool operator == (const Vec2 &v) const
|
|
|
- {
|
|
|
- return (std::abs(x_ - v.x()) < _EPSILON &&
|
|
|
- std::abs(y_ - v.y()) < _EPSILON);
|
|
|
- }
|
|
|
-
|
|
|
- // ----------------------------------------
|
|
|
-
|
|
|
- /*
|
|
|
- * Return the unit vector Vec2(cos(angle), sin(angle)),
|
|
|
- * The param 'angle' should be in radians.
|
|
|
- */
|
|
|
- static Vec2 unitVec2(const double angle)
|
|
|
- {
|
|
|
- return Vec2(cos(angle), sin(angle));
|
|
|
- }
|
|
|
-
|
|
|
- // ----------------------------------------
|
|
|
-
|
|
|
- /*
|
|
|
- * Access x and y components
|
|
|
- */
|
|
|
- double x() const { return x_; }
|
|
|
- double y() const { return y_; }
|
|
|
-
|
|
|
- // ----------------------------------------
|
|
|
-
|
|
|
- /*
|
|
|
- * Set x and y components
|
|
|
- */
|
|
|
- void set_x(const double x) { x_ = x; }
|
|
|
- void set_y(const double y) { y_ = y; }
|
|
|
-
|
|
|
- // ----------------------------------------
|
|
|
-
|
|
|
- /*
|
|
|
- * Operations with other scalars,
|
|
|
- * vec2 is the left operand, scalar is the right operand.
|
|
|
- */
|
|
|
-
|
|
|
- // ----------------------------------------
|
|
|
-
|
|
|
- // add a scalar
|
|
|
- Vec2 operator + (double c) const { return Vec2(x() + c, y() + c); }
|
|
|
- // subtract a scalar
|
|
|
- Vec2 operator - (double c) const { return Vec2(x() - c, y() - c); }
|
|
|
- // multiply a scalar
|
|
|
- Vec2 operator * (double c) const { return Vec2(x() * c, y() * c); }
|
|
|
- // divide by a scalar
|
|
|
- Vec2 operator / (double c) const { return Vec2(x() / c, y() / c); }
|
|
|
- // in-place add a scalar
|
|
|
- Vec2 operator += (double c) { x_ += c; y_ += c; return (*this); }
|
|
|
- // in-place subtract a scalar
|
|
|
- Vec2 operator -= (double c) { x_ -= c; y_ -= c; return (*this); }
|
|
|
- // in-place multiply a scalar
|
|
|
- Vec2 operator *= (double c) { x_ *= c; y_ *= c; return (*this); }
|
|
|
- // in-place divide by a scalar
|
|
|
- Vec2 operator /= (double c) { x_ /= c; y_ /= c; return (*this); }
|
|
|
-
|
|
|
- // ----------------------------------------
|
|
|
-
|
|
|
- /*
|
|
|
- * Operations with other vec2
|
|
|
- */
|
|
|
-
|
|
|
- // ----------------------------------------
|
|
|
-
|
|
|
- // add two vectors
|
|
|
- Vec2 operator + (const Vec2 &v) const { return Vec2(x() + v.x(), y() + v.y()); }
|
|
|
- // subtract another vector
|
|
|
- Vec2 operator - (const Vec2 &v) const { return Vec2(x() - v.x(), y() - v.y()); }
|
|
|
- // multiply two vectors as complex numbers
|
|
|
- Vec2 operator * (const Vec2 &v) const
|
|
|
- {
|
|
|
- double x1 = x() * v.x() - y() * v.y();
|
|
|
- double y1 = x() * v.y() + y() * v.x();
|
|
|
- return Vec2(x1, y1);
|
|
|
- }
|
|
|
- // division as complex numbers
|
|
|
- Vec2 operator / (const Vec2 &v) const
|
|
|
- {
|
|
|
- double snorm = v.squared_norm();
|
|
|
- return Vec2(this->dot(v) / snorm, -this->cross(v) / snorm);
|
|
|
- }
|
|
|
- // in-place vector addition
|
|
|
- Vec2 operator += (const Vec2 &v) { x_ += v.x(); y_ += v.y(); return (*this); }
|
|
|
- // in-place vector subtraction
|
|
|
- Vec2 operator -= (const Vec2 &v) { x_ -= v.x(); y_ -= v.y(); return (*this); }
|
|
|
- // in-place vector multiplication as complex numbers
|
|
|
- Vec2 operator *= (const Vec2 &v)
|
|
|
- {
|
|
|
- double x1 = x() * v.x() - y() * v.y();
|
|
|
- double y1 = x() * v.y() + y() * v.x();
|
|
|
- x_ = x1;
|
|
|
- y_ = y1;
|
|
|
- return (*this);
|
|
|
- }
|
|
|
- // in-place vector division as complex numbers
|
|
|
- Vec2 operator /= (const Vec2 &v)
|
|
|
- {
|
|
|
- double snorm = v.squared_norm();
|
|
|
- double x1 = this->dot(v) / snorm;
|
|
|
- double y1 = -this->cross(v) / snorm;
|
|
|
- x_ = x1;
|
|
|
- y_ = y1;
|
|
|
- return (*this);
|
|
|
- }
|
|
|
-
|
|
|
- // ----------------------------------------
|
|
|
-
|
|
|
- /*
|
|
|
- * Vector util functions
|
|
|
- */
|
|
|
-
|
|
|
- // ----------------------------------------
|
|
|
-
|
|
|
- // Return squared norm
|
|
|
- double squared_norm() const { return x() * x() + y() * y(); }
|
|
|
-
|
|
|
- // Return the usual Euclidean norm
|
|
|
- double norm() const { return sqrt(x() * x() + y() * y()); }
|
|
|
-
|
|
|
- // Inner product of two vectors
|
|
|
- double dot(const Vec2 &v) const { return x() * v.x() + y() * v.y(); }
|
|
|
-
|
|
|
- // Angle with the positive x-axis in radians
|
|
|
- double angle() const { return atan2(y(), x()); }
|
|
|
-
|
|
|
- // Angle between two vectors
|
|
|
- double angle(const Vec2 &v) const
|
|
|
- {
|
|
|
- return acos(this->dot(v) / (norm() * v.norm()));
|
|
|
- }
|
|
|
-
|
|
|
- // Distance between two vectors
|
|
|
- double dist(const Vec2 &v) const { return (*this - v).norm(); }
|
|
|
-
|
|
|
- // Squared distance between two vectors
|
|
|
- double squared_dist(const Vec2 &v) const { return (*this - v).squared_norm(); }
|
|
|
-
|
|
|
- // Cross product of two vectors
|
|
|
- double cross(const Vec2 &v) const { return x() * v.y() - y() * v.x(); }
|
|
|
-
|
|
|
- // Return a normalized version of this vector
|
|
|
- Vec2 normalize() const
|
|
|
- {
|
|
|
- double s = norm();
|
|
|
- return (*this) / s;
|
|
|
- }
|
|
|
-
|
|
|
- // Translate a vector
|
|
|
- Vec2 translate(double tx, double ty) const { return Vec2(x() + tx, y() + ty); }
|
|
|
-
|
|
|
- // Rotate a vector by angle
|
|
|
- Vec2 rotate(const double theta) const
|
|
|
- {
|
|
|
- double ct = cos(theta), st = sin(theta);
|
|
|
- double x1 = x() * ct - y() * st;
|
|
|
- double y1 = x() * ct + y() * st;
|
|
|
- return Vec2(x1, y1);
|
|
|
- }
|
|
|
-
|
|
|
- // return a perpendicular vector to this one
|
|
|
- Vec2 perp() const { return Vec2(-y(), x()); }
|
|
|
-
|
|
|
-private:
|
|
|
- double x_;
|
|
|
- double y_;
|
|
|
-};
|
|
|
-
|
|
|
-// ----------------------------------------
|
|
|
-
|
|
|
-/*
|
|
|
- * Vec2 operations as right operand
|
|
|
-*/
|
|
|
-
|
|
|
-// ----------------------------------------
|
|
|
-
|
|
|
-// print formatting
|
|
|
-std::ostream & operator << (std::ostream &out, const Vec2 &v)
|
|
|
-{
|
|
|
- out << "Vec2(" << v.x() << ", " << v.y() << ")";
|
|
|
- return out;
|
|
|
-}
|
|
|
-
|
|
|
-// add another scalar
|
|
|
-Vec2 operator + (double c, const Vec2 &v) { return Vec2(v.x() + c, v.y() + c); }
|
|
|
-// subtract another scalar
|
|
|
-Vec2 operator - (double c, const Vec2 &v) { return Vec2(c - v.x(), c - v.y()); }
|
|
|
-// multiply another scalar
|
|
|
-Vec2 operator * (double c, const Vec2 &v) { return Vec2(v.x() * c, v.y() * c); }
|
|
|
-// divide another scalar
|
|
|
-Vec2 operator / (double c, const Vec2 &v)
|
|
|
-{
|
|
|
- double snorm = v.squared_norm();
|
|
|
- return Vec2(v.x() * c / snorm, -v.y() * c / snorm);
|
|
|
-}
|
|
|
-
|
|
|
-// ----------------------------------------
|
|
|
-
|
|
|
-/*
|
|
|
- * Vector util functions
|
|
|
-*/
|
|
|
-
|
|
|
-// ----------------------------------------
|
|
|
-
|
|
|
-// Inner product
|
|
|
-double vdot(const Vec2 &v1, const Vec2 &v2) { return v1.dot(v2); }
|
|
|
-
|
|
|
-// Cross
|
|
|
-double vcross(const Vec2 &v1, const Vec2 &v2) { return v1.cross(v2); }
|
|
|
-
|
|
|
-// Vector length
|
|
|
-double vlength(const Vec2 &v) { return v.norm(); }
|
|
|
-
|
|
|
-// Angle with positive x-axis
|
|
|
-double vangle(const Vec2 &v) { return v.angle(); }
|
|
|
-
|
|
|
-// Angle between two vectors
|
|
|
-double vangle(const Vec2 &v1, const Vec2 &v2) { return v1.angle(v2); }
|
|
|
-
|
|
|
-// distance between two vectors
|
|
|
-double vdist(const Vec2 &v1, const Vec2 &v2) { return v1.dist(v2); }
|
|
|
-
|
|
|
-// squared distance between two vectors
|
|
|
-double vsquared_dist(const Vec2 &v1, const Vec2 &v2) { return v1.squared_dist(v2); }
|
|
|
-
|
|
|
-// normalize a vector
|
|
|
-Vec2 vnormalize(const Vec2 &v) { return v.normalize(); }
|
|
|
-
|
|
|
-// return a perpendicular one
|
|
|
-Vec2 vperp(const Vec2 &v) { return v.perp(); }
|
|
|
-
|
|
|
-// rotate a vector
|
|
|
-Vec2 vrotate(const Vec2 &v, double theta) { return v.rotate(theta); }
|
|
|
-
|
|
|
-// return a unit vector of given direction
|
|
|
-Vec2 vdir(const double angle) { return Vec2::unitVec2(angle); }
|
|
|
-
|
|
|
-// return a linear combination of two vectors
|
|
|
-Vec2 vinterp(const Vec2 &v1, const Vec2 &v2, double t) { return v1 * (1 - t) + v2 * t; }
|
|
|
-
|
|
|
-}
|
|
|
-}
|
|
|
-
|
|
|
-#endif // VEC2_H
|