1 /***************************************************************************
2 
3     file                 : linalg.h
4     created              : Wed Feb 18 01:20:19 CET 2003
5     copyright            : (C) 2003-2004 Bernhard Wymann
6     email                : berniw@bluewin.ch
7     version              : $Id: linalg.h,v 1.8 2005/08/05 08:54:09 berniw Exp $
8 
9  ***************************************************************************/
10 
11 /***************************************************************************
12  *                                                                         *
13  *   This program is free software; you can redistribute it and/or modify  *
14  *   it under the terms of the GNU General Public License as published by  *
15  *   the Free Software Foundation; either version 2 of the License, or     *
16  *   (at your option) any later version.                                   *
17  *                                                                         *
18  ***************************************************************************/
19 
20 #ifndef _LINALG_H_
21 #define _LINALG_H_
22 
sign(float d)23 inline float sign(float d) {
24 	return (d >= 0.0f) ? 1.0f : -1.0f;
25 }
26 
27 
28 class v2d {
29 	public:
30 		/* constructors */
v2d()31 		v2d() {}
v2d(const v2d & src)32 		v2d(const v2d &src) { this->x = src.x; this->y = src.y; }
v2d(float x,float y)33 		v2d(float x, float y) { this->x = x; this->y = y; }
34 
35 		/* operators */
36 		v2d& operator=(const v2d &src);         /* assignment */
37 		v2d operator+(const v2d &src) const;    /* addition */
38 		v2d operator-(void) const;              /* negation */
39 		v2d operator-(const v2d &src) const;    /* subtraction */
40 		v2d operator*(const float s) const;     /* multiply with scalar */
41 		float operator*(const v2d &src) const;  /* dot product */
42 		friend v2d operator*(const float s, const v2d & src);
43 
44 		/* methods */
45 		float len(void) const;
46 		void normalize(void);
47 		float dist(const v2d &p) const;
48 		float cosalpha(const v2d &p2, const v2d &center) const;
49 		v2d rotate(const v2d &c, float arc) const;
50 
51 		/* data */
52 		float x;
53 		float y;
54 };
55 
56 
57 /* assignment */
58 inline v2d& v2d::operator=(const v2d &src)
59 {
60     x = src.x; y = src.y; return *this;
61 }
62 
63 
64 /* add *this + src (vector addition) */
65 inline v2d v2d::operator+(const v2d &src) const
66 {
67     return v2d(x + src.x, y + src.y);
68 }
69 
70 
71 /* negation of *this */
72 inline v2d v2d::operator-(void) const
73 {
74     return v2d(-x, -y);
75 }
76 
77 
78 /* compute *this - src (vector subtraction) */
79 inline v2d v2d::operator-(const v2d &src) const
80 {
81     return v2d(x - src.x, y - src.y);
82 }
83 
84 
85 /* scalar product */
86 inline float v2d::operator*(const v2d &src) const
87 {
88     return src.x*x + src.y*y;
89 }
90 
91 
92 /* multiply vector with scalar (v2d*float) */
93 inline v2d v2d::operator*(const float s) const
94 {
95     return v2d(s*x, s*y);
96 }
97 
98 
99 /* multiply scalar with vector (float*v2d) */
100 inline v2d operator*(const float s, const v2d & src)
101 {
102     return v2d(s*src.x, s*src.y);
103 }
104 
105 
106 /* compute cosine of the angle between vectors *this-c and p2-c */
cosalpha(const v2d & p2,const v2d & c)107 inline float v2d::cosalpha(const v2d &p2, const v2d &c) const
108 {
109 	v2d l1 = *this-c;
110 	v2d l2 = p2 - c;
111 	return (l1*l2)/(l1.len()*l2.len());
112 }
113 
114 
115 /* rotate vector arc radians around center c */
rotate(const v2d & c,float arc)116 inline v2d v2d::rotate(const v2d &c, float arc) const
117 {
118 	v2d d = *this-c;
119 	float sina = (float) sin(arc), cosa = (float) cos(arc);
120 	return c + v2d(d.x*cosa-d.y*sina, d.x*sina+d.y*cosa);
121 }
122 
123 
124 /* compute the length of the vector */
len(void)125 inline float v2d::len(void) const
126 {
127 	return (float) sqrt(x*x+y*y);
128 }
129 
130 
131 /* distance between *this and p */
dist(const v2d & p)132 inline float v2d::dist(const v2d &p) const
133 {
134 	return (float) sqrt((p.x-x)*(p.x-x)+(p.y-y)*(p.y-y));
135 }
136 
137 
138 /* normalize the vector */
normalize(void)139 inline void v2d::normalize(void)
140 {
141 	float l = this->len();
142 	x /= l; y /= l;
143 }
144 
145 
146 class Straight {
147     public:
148         /* constructors */
Straight()149         Straight() {}
Straight(float x,float y,float dx,float dy)150         Straight(float x, float y, float dx, float dy)
151             {  p.x = x; p.y = y; d.x = dx; d.y = dy; d.normalize(); }
Straight(const v2d & anchor,const v2d & dir)152         Straight(const v2d &anchor, const v2d &dir)
153             { p = anchor; d = dir; d.normalize(); }
154 
155         /* methods */
156         v2d intersect(const Straight &s) const;
157         float dist(const v2d &p) const;
158 
159         /* data */
160         v2d p;          /* point on the straight */
161         v2d d;          /* direction of the straight */
162 };
163 
164 
165 /* intersection point of *this and s */
intersect(const Straight & s)166 inline v2d Straight::intersect(const Straight &s) const
167 {
168     float t = -(d.x*(s.p.y-p.y)+d.y*(p.x-s.p.x))/(d.x*s.d.y-d.y*s.d.x);
169     return s.p + s.d*t;
170 }
171 
172 
173 /* distance of point s from straight *this */
dist(const v2d & s)174 inline float Straight::dist(const v2d &s) const
175 {
176     v2d d1 = s - p;
177     v2d d3 = d1 - d*d1*d;
178     return d3.len();
179 }
180 
181 #endif // _LINALG_H_
182 
183