Line2

See: line2.h line2.cpp

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