PVector
Data / CompositeDescription
A class to describe a two or three dimensional vector. Commonly used to represent position, velocity, or direction.
Syntax
PVector v
PVector v(x, y)
PVector v(x, y, z)
Parameters
| Name | Type | Description |
|---|---|---|
| x | float | x component (optional) |
| y | float | y component (optional) |
| z | float | z component (optional) |
Returns
PVectorMethods
| mag() | Magnitude (length) of the vector |
| magSq() | Magnitude squared |
| add(PVector v) | Add another vector |
| sub(PVector v) | Subtract another vector |
| mult(float s) | Multiply by scalar |
| div(float s) | Divide by scalar |
| normalize() | Normalize to unit length |
| limit(float max) | Limit the magnitude |
| setMag(float m) | Set the magnitude |
| dot(PVector v) | Dot product |
| cross(PVector v) | Cross product |
| dist(PVector v) | Distance to another vector |
| heading() | Angle the vector makes with positive x-axis |
| angleBetween(PVector v) | Angle between two vectors |
| lerp(PVector v, float t) | Interpolate towards another vector |
| rotate(float angle) | Rotate by an angle (2D) |
| copy() | Return a copy |
| toString() | String representation |
| PVector::fromAngle(float a) | Create from angle (static) |
| PVector::random2D() | Random 2D unit vector (static) |
| PVector::random3D() | Random 3D unit vector (static) |
Under the Hood
From Processing.h:
class PVector {
public:
float x, y, z;
// Constructors
PVector() : x(0), y(0), z(0) {}
PVector(float x, float y) : x(x), y(y), z(0) {}
PVector(float x, float y, float z): x(x), y(y), z(z) {}
// Setters
PVector& set(float _x, float _y, float _z=0) { x=_x; y=_y; z=_z; return *this; }
PVector& set(const PVector& v) { x=v.x; y=v.y; z=v.z; return *this; }
PVector copy() const { return PVector(x, y, z); }
// Magnitude
float mag() const { return std::sqrt(x*x + y*y + z*z); }
float magSq() const { return x*x + y*y + z*z; }
// Arithmetic (in-place)
PVector& add(float _x, float _y, float _z=0) { x+=_x; y+=_y; z+=_z; return *this; }
PVector& add(const PVector& v) { x+=v.x; y+=v.y; z+=v.z; return *this; }
PVector& sub(float _x, float _y, float _z=0) { x-=_x; y-=_y; z-=_z; return *this; }
PVector& sub(const PVector& v) { x-=v.x; y-=v.y; z-=v.z; return *this; }
PVector& mult(float s) { x*=s; y*=s; z*=s; return *this; }
PVector& div(float s) { x/=s; y/=s; z/=s; return *this; }
// Arithmetic (static, returns new vector)
static PVector add(const PVector& a, const PVector& b) { return PVector(a.x+b.x, a.y+b.y, a.z+b.z); }
static PVector sub(const PVector& a, const PVector& b) { return PVector(a.x-b.x, a.y-b.y, a.z-b.z); }
static PVector mult(const PVector& v, float s) { return PVector(v.x*s, v.y*s, v.z*s); }
static PVector div(const PVector& v, float s) { return PVector(v.x/s, v.y/s, v.z/s); }
// Operators
PVector operator+(const PVector& v) const { return PVector(x+v.x, y+v.y, z+v.z); }
PVector operator-(const PVector& v) const { return PVector(x-v.x, y-v.y, z-v.z); }
PVector operator*(float s) const { return PVector(x*s, y*s, z*s); }
PVector operator/(float s) const { return PVector(x/s, y/s, z/s); }
PVector& operator+=(const PVector& v) { return add(v); }
PVector& operator-=(const PVector& v) { return sub(v); }
PVector& operator*=(float s) { return mult(s); }
PVector& operator/=(float s) { return div(s); }
bool operator==(const PVector& v) const { return x==v.x && y==v.y && z==v.z; }
bool operator!=(const PVector& v) const { return !(*this==v); }
// Dot / cross product
float dot(const PVector& v) const { return x*v.x + y*v.y + z*v.z; }
float dot(float _x, float _y, float _z=0) const { return x*_x + y*_y + z*_z; }
static float dot(const PVector& a, const PVector& b) { return a.dot(b); }
PVector cross(const PVector& v) const { return PVector(y*v.z-z*v.y, z*v.x-x*v.z, x*v.y-y*v.x); }
static PVector cross(const PVector& a, const PVector& b) { return a.cross(b); }
// Normalization / limits
PVector& normalize() { float m=mag(); if(m>0) div(m); return *this; }
PVector normalized() const { PVector v(*this); return v.normalize(); }
PVector& limit(float mx) { if(magSq()>mx*mx){ normalize(); mult(mx); } return *this; }
PVector& setMag(float m) { normalize(); mult(m); return *this; }
// Distance / angle
float dist(const PVector& v) const { float dx=x-v.x,dy=y-v.y,dz=z-v.z; return std::sqrt(dx*dx+dy*dy+dz*dz); }
static float dist(const PVector& a, const PVector& b) { return a.dist(b); }
float heading() const { return std::atan2(y, x); }
float angleBetween(const PVector& v) const {
float m = mag() * v.mag();
if (m == 0) return 0;
float c = dot(v) / m;
c = c < -1 ? -1 : (c > 1 ? 1 : c);
return std::acos(c);
}
static float angleBetween(const PVector& a, const PVector& b) { return a.angleBetween(b); }
// Mutation
PVector& rotate(float t) { float c=std::cos(t),s=std::sin(t),nx=x*c-y*s,ny=x*s+y*c; x=nx; y=ny; return *this; }
PVector& lerp(const PVector& v, float t) { x+=(v.x-x)*t; y+=(v.y-y)*t; z+=(v.z-z)*t; return *this; }
PVector& lerp(float _x, float _y, float _z, float t) { x+=(_x-x)*t; y+=(_y-y)*t; z+=(_z-z)*t; return *this; }
static PVector lerp(const PVector& a, const PVector& b, float t) {
return PVector(a.x+(b.x-a.x)*t, a.y+(b.y-a.y)*t, a.z+(b.z-a.z)*t);
}
// Static constructors
static PVector fromAngle(float a, float len=1.0f) { return PVector(std::cos(a)*len, std::sin(a)*len); }
static PVector random2D() {
float a = static_cast<float>(rand()) / RAND_MAX * 6.28318f;
return fromAngle(a);
}
static PVector random3D() {
float t = static_cast<float>(rand()) / RAND_MAX * 6.28318f;
float p = std::acos(2.0f * static_cast<float>(rand()) / RAND_MAX - 1.0f);
return PVector(std::sin(p)*std::cos(t), std::sin(p)*std::sin(t), std::cos(p));
}
std::string toString() const {
std::ostringstream ss;
ss << "[ " << x << ", " << y << ", " << z << " ]";
return ss.str();
}
};
return PVector(verts[i].x, verts[i].y, verts[i].z);
inline PVector createVector(float x, float y, float z=0) { return PVector(x, y, z);