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