summaryrefslogtreecommitdiffstats
path: root/kivio/kiviopart/kiviosdk/tkmath.h
blob: 0edb6b37b1917f3154c5419503cb55585c7ba7c7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/*
 * Kivio - Visual Modelling and Flowcharting
 * Copyright (C) 2000-2001 theKompany.com & Dave Marotti
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */
#ifndef _TKVECTOR_H
#define _TKVECTOR_H

#include <math.h>

class TKVec2
{
protected:
   double m_x, m_y;

public:
   TKVec2(const double &_x, const double &_y)
      { m_x = _x; m_y=_y; }

   inline double dotProduct( const TKVec2 &v2 ) const
      { return m_x*v2.m_x + m_y*v2.m_y; }

   inline double crossProduct( const TKVec2 &v2 ) const
      { return ( m_x*v2.m_y - m_y*v2.m_x ); }

   inline double magnitude() const
      { return sqrt(m_x*m_x + m_y*m_y); }

   inline void normalize()
      { double l=this->magnitude(); m_x/=l; m_y/=l; }

   inline void scale( const double &sx, const double &sy )
      { m_x *= sx; m_y *= sy; }

   inline void scale( const TKVec2 &v )
      { m_x *= v.m_x; m_y *= v.m_y; }

   inline void scale( const double &s )
      { m_x*=s; m_y*=s; }

   inline TKVec2 getPerpendicular() const
      { return TKVec2(-m_y, m_x); }

   inline void reverse()
      { m_x*=-1.0f; m_y*=-1.0f; }

   inline void rotate( const double &rad )
      { 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;}

   inline void rotateDeg( const double &deg )
      { double newX, newY, rad=deg*3.14159f/180.0f; 
      newX= m_x*cos(rad) - m_y*sin(rad); newY=m_x*sin(rad)+m_y*cos(rad); m_x=newX; m_y=newY;}

   inline void translate( const double &tx, const double &ty )
      { m_x += tx; m_y += ty; }

   inline double angle( const TKVec2 &v )
      { return acos( (this->dotProduct(v)) / (this->magnitude() * v.magnitude()) ); }

   inline double x() { return m_x; }
   inline double y() { return m_y; }

   inline void setX(const double &_x) { m_x=_x; }
   inline void setY(const double &_y) { m_y=_y; }

   inline void set(const double &_x, const double &_y) {m_x=_x; m_y=_y;}
};

inline double shortestDistance(double sx, double sy, double ex, double ey, double px, double py )
{
   TKVec2 u(sx-ex, sy-ey);
   TKVec2 pq(sx-px, sy-py);

   double magTop = fabs( pq.crossProduct(u) );
   double magU = u.magnitude();

   // Eeeewww
   if( magU==0.0f )
   {
      return -1.0f;
   }

   return magTop / magU;
}

inline bool collisionLine( double sx, double sy, double ex, double ey, double px, double py, double threshold )
{
   double minx, miny, maxx, maxy;
   
   if( sx < ex ) {
      minx = sx;
      maxx = ex;
   }
   else {
      minx = ex;
      maxx = sx;
   }
   
   minx -= threshold;
   maxx += threshold;

   if( sy < ey ) {
      miny = sy;
      maxy = ey;
   }
   else {
      miny = ey;
      maxy = sy;
   }

   miny -= threshold;
   maxy += threshold;

   if( !(px >= minx &&
	 px <= maxx &&
	 py >= miny &&
	 py <= maxy ) )
   {
      return false;
   }

   if( shortestDistance( sx, sy, ex, ey, px, py ) <= threshold )
      return true;

   return false;
}

#endif