2 * This file is part of NumptyPhysics
3 * Copyright (C) 2008 Tim Edmonds
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 3 of the
8 * License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
21 static float calcDistanceToLine( const Vec2
& pt
,
22 const Vec2
& l1
, const Vec2
& l2
,
23 bool* withinLine
=NULL
)
27 float mag
= l
.Normalize();
28 float dist
= b2Cross( w
, l
);
30 float dot
= b2Dot( l
, w
);
31 *withinLine
= ( dot
>= 0.0f
&& dot
<= mag
);
37 static float calcDistance( const Vec2
& l1
, const Vec2
& l2
)
39 return b2Vec2(l1
-l2
).Length();
43 float Segment::distanceTo( const Vec2
& p
)
46 float d
= calcDistanceToLine( p
, m_p1
, m_p2
, &withinLine
);
47 if ( !(m_p1
== m_p2
) && withinLine
) {
50 return b2Min( calcDistance( p
, m_p2
), calcDistance( p
, m_p1
) );
55 Path::Path() : Array
<Vec2
>() {}
57 Path::Path( int n
, Vec2
* p
) : Array
<Vec2
>(n
, p
) {}
59 void Path::makeRelative()
61 for (int i
=size()-1; i
>=0; i
--)
66 Path
& Path::translate(const Vec2
& xlate
)
68 for (int i
=0;i
<size();i
++)
73 Path
& Path::rotate(const b2Mat22
& rot
)
75 int j1
= FLOAT_TO_FIXED(rot
.col1
.x
);
76 int k1
= FLOAT_TO_FIXED(rot
.col1
.y
);
77 int j2
= FLOAT_TO_FIXED(rot
.col2
.x
);
78 int k2
= FLOAT_TO_FIXED(rot
.col2
.y
);
81 for (int i
=0;i
<size();i
++) {
82 //at(i) = b2Mul( rot, at(i) );
83 at(i
) = Vec2( FIXED_TO_INT(j1
* at(i
).x
+ j2
* at(i
).y
),
84 FIXED_TO_INT(k1
* at(i
).x
+ k2
* at(i
).y
) );
89 Path
& Path::scale(float factor
)
91 int f
= FLOAT_TO_FIXED(factor
);
92 for (int i
=0;i
<size();i
++) {
93 at(i
).x
= FIXED_TO_INT(at(i
).x
* f
);
94 at(i
).y
= FIXED_TO_INT(at(i
).y
* f
);
99 void Path::simplify( float threshold
)
101 bool keepflags
[size()];
102 memset( &keepflags
[0], 0, sizeof(keepflags
) );
104 keepflags
[0] = keepflags
[size()-1] = true;
105 simplifySub( 0, size()-1, threshold
, &keepflags
[0] );
108 for ( int i
=0; i
<size(); i
++ ) {
109 if ( keepflags
[i
] ) {
113 //printf("simplify %f %dpts to %dpts\n",threshold,size(),k);
116 // remove duplicate points (shouldn't be any)
117 for ( int i
=size()-1; i
>0; i
-- ) {
118 if ( at(i
) == at(i
-1) ) {
119 //printf("alert: duplicate pt!\n");
125 void Path::simplifySub( int first
, int last
, float threshold
, bool* keepflags
)
127 float furthestDist
= threshold
;
128 int furthestIndex
= 0;
129 if ( last
- first
> 1 ) {
130 Segment
s( at(first
), at(last
) );
131 for ( int i
=first
+1; i
<last
; i
++ ) {
132 float d
= s
.distanceTo( at(i
) );
133 if ( d
> furthestDist
) {
138 if ( furthestIndex
!= 0 ) {
139 keepflags
[furthestIndex
] = true;
140 simplifySub( first
, furthestIndex
, threshold
, keepflags
);
141 simplifySub( furthestIndex
, last
, threshold
, keepflags
);
146 Rect
Path::bbox() const
148 Rect
r( at(0), at(0) );
149 for ( int i
=1; i
<size(); i
++ ) {