tkmath.h
1/*
2 * Kivio - Visual Modelling and Flowcharting
3 * Copyright (C) 2000-2001 theKompany.com & Dave Marotti
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 */
19#ifndef _TKVECTOR_H
20#define _TKVECTOR_H
21
22#include <math.h>
23
24class TKVec2
25{
26protected:
27 double m_x, m_y;
28
29public:
30 TKVec2(const double &_x, const double &_y)
31 { m_x = _x; m_y=_y; }
32
33 inline double dotProduct( const TKVec2 &v2 ) const
34 { return m_x*v2.m_x + m_y*v2.m_y; }
35
36 inline double crossProduct( const TKVec2 &v2 ) const
37 { return ( m_x*v2.m_y - m_y*v2.m_x ); }
38
39 inline double magnitude() const
40 { return sqrt(m_x*m_x + m_y*m_y); }
41
42 inline void normalize()
43 { double l=this->magnitude(); m_x/=l; m_y/=l; }
44
45 inline void scale( const double &sx, const double &sy )
46 { m_x *= sx; m_y *= sy; }
47
48 inline void scale( const TKVec2 &v )
49 { m_x *= v.m_x; m_y *= v.m_y; }
50
51 inline void scale( const double &s )
52 { m_x*=s; m_y*=s; }
53
54 inline TKVec2 getPerpendicular() const
55 { return TKVec2(-m_y, m_x); }
56
57 inline void reverse()
58 { m_x*=-1.0f; m_y*=-1.0f; }
59
60 inline void rotate( const double &rad )
61 { double newX, newY; newX= m_x*cos(rad) - m_y*sin(rad); newY=m_x*sin(rad)+m_y*cos(rad); m_x=newX; m_y=newY;}
62
63 inline void rotateDeg( const double &deg )
64 { double newX, newY, rad=deg*3.14159f/180.0f;
65 newX= m_x*cos(rad) - m_y*sin(rad); newY=m_x*sin(rad)+m_y*cos(rad); m_x=newX; m_y=newY;}
66
67 inline void translate( const double &tx, const double &ty )
68 { m_x += tx; m_y += ty; }
69
70 inline double angle( const TKVec2 &v )
71 { return acos( (this->dotProduct(v)) / (this->magnitude() * v.magnitude()) ); }
72
73 inline double x() { return m_x; }
74 inline double y() { return m_y; }
75
76 inline void setX(const double &_x) { m_x=_x; }
77 inline void setY(const double &_y) { m_y=_y; }
78
79 inline void set(const double &_x, const double &_y) {m_x=_x; m_y=_y;}
80};
81
82inline double shortestDistance(double sx, double sy, double ex, double ey, double px, double py )
83{
84 TKVec2 u(sx-ex, sy-ey);
85 TKVec2 pq(sx-px, sy-py);
86
87 double magTop = fabs( pq.crossProduct(u) );
88 double magU = u.magnitude();
89
90 // Eeeewww
91 if( magU==0.0f )
92 {
93 return -1.0f;
94 }
95
96 return magTop / magU;
97}
98
99inline bool collisionLine( double sx, double sy, double ex, double ey, double px, double py, double threshold )
100{
101 double minx, miny, maxx, maxy;
102
103 if( sx < ex ) {
104 minx = sx;
105 maxx = ex;
106 }
107 else {
108 minx = ex;
109 maxx = sx;
110 }
111
112 minx -= threshold;
113 maxx += threshold;
114
115 if( sy < ey ) {
116 miny = sy;
117 maxy = ey;
118 }
119 else {
120 miny = ey;
121 maxy = sy;
122 }
123
124 miny -= threshold;
125 maxy += threshold;
126
127 if( !(px >= minx &&
128 px <= maxx &&
129 py >= miny &&
130 py <= maxy ) )
131 {
132 return false;
133 }
134
135 if( shortestDistance( sx, sy, ex, ey, px, py ) <= threshold )
136 return true;
137
138 return false;
139}
140
141#endif