line2.h
/*\file line2.h */ /*! line2 is a two dimensional line */ #pragma once #include <iostream> #include <math.h> #include "vec2.h" //! defines two-dimensional point class Line2 { public: Line2() {set(0.0,0.0,0.0,0.0); } //!< default no-argument constructor ~Line2() {} //!< destructor //! construct Line2 from origin to specified point Line2(Vec2 to) { set(0.0,0.0,to[0],to[1]); } //! construct Line2 from origin to (x,y) Line2(double x, double y) { set(0.0,0.0,x,y); } //! constructs Line2 from (x1,y1) to (x2,y2) Line2(double x1, double y1, double x2, double y2) { set(x1,y1,x2,y2); } //! constructs Line2 from two points Line2(Vec2 from, Vec2 to) { body[0] = from; body[1] = to; } //! returns length of associated array int rows() const { return 2; } int cols() const { return 2; } Vec2 getDirection() const { return Vec2(body[1][0]-body[0][0],body[1][1]-body[0][1]); } double getAngle() const { return angle(Vec2(1,0),body[1]-body[0]); } double getSize() const { return _hypot(body[1][0]-body[0][0],body[1][1]-body[0][1]); } double getClosestPosition(Vec2 pt) const { Vec2 k = getDirection(); Vec2 r(pt[0] - body[0][0],pt[1]-body[0][1]); return dot(k,r)/dot(k,k); } //! find point on parametric line (1-u)*pt1 + u*pt2; Vec2 lerp(double u) { return (body[0]*(1.0-u)+body[1]*u); } //! return pointer to first element Vec2 * pVec2() { return body; } //! const Vec2 &value(int k) const { return body[k]; } //! subscript operator (non-const object) Vec2 &operator[](int k) { return body[k]; } //! subscript operator (const object) const Vec2 &operator[](int k) const { return body[k]; } Line2 &operator+=(const Vec2 &b); //! set Line2 to new value Line2 &set(double x1, double y1, double x2, double y2) { body[0][0]=x1; body[0][1]=y1; body[1][0]=x2; body[1][1]=y2; return *this; } Line2 &from(double x, double y) { body[0][0]=x; body[0][1]=y; return *this; } Line2 &from(Vec2 &src) { body[0]=src; return *this; } Line2 &to(double x, double y) { body[1][0]=x; body[1][1]=y; return *this; } Line2 &to(Vec2 &src) { body[1]=src; return *this; } Line2 &away(double r, double theta) { Vec2 angled(theta); sum(body[1],body[0],angled.scale(r)); return *this; } //operator overloads friend Line2 operator+(const Line2&a, Vec2 &b); friend Line2 operator-(const Line2&a, Vec2 &b); friend Line2 operator-(const Line2&a); //! iostream output friend std::ostream& operator << (std::ostream& s, const Line2& v); private: Vec2 body[2]; //!< contains the elements of a 2D line }; //! returns Line2 += Vec2; inline Line2 &Line2::operator+=(const Vec2 &b) { Line2 &a = *this; a[0] += b; a[1] += b; return *this; } //! returns Line2 + Vec2 inline Line2 operator+(const Line2 &a, const Vec2 &b) { return Line2(a[0]+b,a[1]+b); } //! returns Line2 - Vec2 inline Line2 operator-(const Line2 &a, const Vec2 &b) { return Line2(a[0]-b,a[1]-b); } //! returns -a inline Line2 operator-(const Line2 &a) { return Line2(a[1],a[0]); } double angle(const Line2 &a, const Line2 &b); Line2 rotate(const Line2 &a, double theta);
line2.cpp
/* \file line2.cpp * */ #include <stdio.h> #include <math.h> #include <iostream> #include "line2.h" //! overloaded insertion operator << std::ostream& operator << (std::ostream& s, const Line2& v) { //s << v.body[0] << ":" << v.body[1]; //s << v.value(0) << ":" << v.value(1); s << v[0] << ":" << v[1]; return s ; } //! returns angle (in degrees) between two lines double angle(const Line2 &a, const Line2 &b) { return angle(a[1]-a[0],b[1]-b[0]); } /* //! returns vec rotated by angle theta in degrees /* Line2 rotate(const Line2 &a, double theta) { double c, s; const double radg = atan(1.0)/45.0; theta *= radg; c = cos(theta); s = sin(theta); return Line2(c*a[0]-s*a[1],s*a[0]+c*a[1]); } */
Maintained by John Loomis, updated Sat Feb 03 11:15:17 2007