| 1 |
/* |
|---|
| 2 |
* Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com |
|---|
| 3 |
* |
|---|
| 4 |
* This software is provided 'as-is', without any express or implied |
|---|
| 5 |
* warranty. In no event will the authors be held liable for any damages |
|---|
| 6 |
* arising from the use of this software. |
|---|
| 7 |
* Permission is granted to anyone to use this software for any purpose, |
|---|
| 8 |
* including commercial applications, and to alter it and redistribute it |
|---|
| 9 |
* freely, subject to the following restrictions: |
|---|
| 10 |
* 1. The origin of this software must not be misrepresented; you must not |
|---|
| 11 |
* claim that you wrote the original software. If you use this software |
|---|
| 12 |
* in a product, an acknowledgment in the product documentation would be |
|---|
| 13 |
* appreciated but is not required. |
|---|
| 14 |
* 2. Altered source versions must be plainly marked as such, and must not be |
|---|
| 15 |
* misrepresented as being the original software. |
|---|
| 16 |
* 3. This notice may not be removed or altered from any source distribution. |
|---|
| 17 |
*/ |
|---|
| 18 |
|
|---|
| 19 |
package Box2D.Collision{ |
|---|
| 20 |
|
|---|
| 21 |
import Box2D.Common.Math.*; |
|---|
| 22 |
import Box2D.Common.*; |
|---|
| 23 |
import Box2D.Collision.Shapes.*; |
|---|
| 24 |
import Box2D.Collision.*; |
|---|
| 25 |
|
|---|
| 26 |
public class b2Distance |
|---|
| 27 |
{ |
|---|
| 28 |
|
|---|
| 29 |
// GJK using Voronoi regions (Christer Ericson) and region selection |
|---|
| 30 |
// optimizations (Casey Muratori). |
|---|
| 31 |
|
|---|
| 32 |
// The origin is either in the region of points[1] or in the edge region. The origin is |
|---|
| 33 |
// not in region of points[0] because that is the old point. |
|---|
| 34 |
static public function ProcessTwo(x1:b2Vec2, x2:b2Vec2, p1s:Array, p2s:Array, points:Array):int |
|---|
| 35 |
{ |
|---|
| 36 |
var points_0:b2Vec2 = points[0]; |
|---|
| 37 |
var points_1:b2Vec2 = points[1]; |
|---|
| 38 |
var p1s_0:b2Vec2 = p1s[0]; |
|---|
| 39 |
var p1s_1:b2Vec2 = p1s[1]; |
|---|
| 40 |
var p2s_0:b2Vec2 = p2s[0]; |
|---|
| 41 |
var p2s_1:b2Vec2 = p2s[1]; |
|---|
| 42 |
|
|---|
| 43 |
// If in point[1] region |
|---|
| 44 |
//b2Vec2 r = -points[1]; |
|---|
| 45 |
var rX:Number = -points_1.x; |
|---|
| 46 |
var rY:Number = -points_1.y; |
|---|
| 47 |
//b2Vec2 d = points[1] - points[0]; |
|---|
| 48 |
var dX:Number = points_0.x - points_1.x; |
|---|
| 49 |
var dY:Number = points_0.y - points_1.y; |
|---|
| 50 |
//float32 length = d.Normalize(); |
|---|
| 51 |
var length:Number = Math.sqrt(dX*dX + dY*dY); |
|---|
| 52 |
dX /= length; |
|---|
| 53 |
dY /= length; |
|---|
| 54 |
|
|---|
| 55 |
//float32 lambda = b2Dot(r, d); |
|---|
| 56 |
var lambda:Number = rX * dX + rY * dY; |
|---|
| 57 |
if (lambda <= 0.0 || length < Number.MIN_VALUE) |
|---|
| 58 |
{ |
|---|
| 59 |
// The simplex is reduced to a point. |
|---|
| 60 |
//*p1Out = p1s[1]; |
|---|
| 61 |
x1.SetV(p1s_1); |
|---|
| 62 |
//*p2Out = p2s[1]; |
|---|
| 63 |
x2.SetV(p2s_1); |
|---|
| 64 |
//p1s[0] = p1s[1]; |
|---|
| 65 |
p1s_0.SetV(p1s_1); |
|---|
| 66 |
//p2s[0] = p2s[1]; |
|---|
| 67 |
p2s_0.SetV(p2s_1); |
|---|
| 68 |
points_0.SetV(points_1); |
|---|
| 69 |
return 1; |
|---|
| 70 |
} |
|---|
| 71 |
|
|---|
| 72 |
// Else in edge region |
|---|
| 73 |
lambda /= length; |
|---|
| 74 |
//*x1 = p1s[1] + lambda * (p1s[0] - p1s[1]); |
|---|
| 75 |
x1.x = p1s_1.x + lambda * (p1s_0.x - p1s_1.x); |
|---|
| 76 |
x1.y = p1s_1.y + lambda * (p1s_0.y - p1s_1.y); |
|---|
| 77 |
//*x2 = p2s[1] + lambda * (p2s[0] - p2s[1]); |
|---|
| 78 |
x2.x = p2s_1.x + lambda * (p2s_0.x - p2s_1.x); |
|---|
| 79 |
x2.y = p2s_1.y + lambda * (p2s_0.y - p2s_1.y); |
|---|
| 80 |
return 2; |
|---|
| 81 |
} |
|---|
| 82 |
|
|---|
| 83 |
// Possible regions: |
|---|
| 84 |
// - points[2] |
|---|
| 85 |
// - edge points[0]-points[2] |
|---|
| 86 |
// - edge points[1]-points[2] |
|---|
| 87 |
// - inside the triangle |
|---|
| 88 |
static public function ProcessThree(x1:b2Vec2, x2:b2Vec2, p1s:Array, p2s:Array, points:Array):int |
|---|
| 89 |
{ |
|---|
| 90 |
var points_0:b2Vec2 = points[0]; |
|---|
| 91 |
var points_1:b2Vec2 = points[1]; |
|---|
| 92 |
var points_2:b2Vec2 = points[2]; |
|---|
| 93 |
var p1s_0:b2Vec2 = p1s[0]; |
|---|
| 94 |
var p1s_1:b2Vec2 = p1s[1]; |
|---|
| 95 |
var p1s_2:b2Vec2 = p1s[2]; |
|---|
| 96 |
var p2s_0:b2Vec2 = p2s[0]; |
|---|
| 97 |
var p2s_1:b2Vec2 = p2s[1]; |
|---|
| 98 |
var p2s_2:b2Vec2 = p2s[2]; |
|---|
| 99 |
|
|---|
| 100 |
//b2Vec2 a = points[0]; |
|---|
| 101 |
var aX:Number = points_0.x; |
|---|
| 102 |
var aY:Number = points_0.y; |
|---|
| 103 |
//b2Vec2 b = points[1]; |
|---|
| 104 |
var bX:Number = points_1.x; |
|---|
| 105 |
var bY:Number = points_1.y; |
|---|
| 106 |
//b2Vec2 c = points[2]; |
|---|
| 107 |
var cX:Number = points_2.x; |
|---|
| 108 |
var cY:Number = points_2.y; |
|---|
| 109 |
|
|---|
| 110 |
//b2Vec2 ab = b - a; |
|---|
| 111 |
var abX:Number = bX - aX; |
|---|
| 112 |
var abY:Number = bY - aY; |
|---|
| 113 |
//b2Vec2 ac = c - a; |
|---|
| 114 |
var acX:Number = cX - aX; |
|---|
| 115 |
var acY:Number = cY - aY; |
|---|
| 116 |
//b2Vec2 bc = c - b; |
|---|
| 117 |
var bcX:Number = cX - bX; |
|---|
| 118 |
var bcY:Number = cY - bY; |
|---|
| 119 |
|
|---|
| 120 |
//float32 sn = -b2Dot(a, ab), sd = b2Dot(b, ab); |
|---|
| 121 |
var sn:Number = -(aX * abX + aY * abY); |
|---|
| 122 |
var sd:Number = (bX * abX + bY * abY); |
|---|
| 123 |
//float32 tn = -b2Dot(a, ac), td = b2Dot(c, ac); |
|---|
| 124 |
var tn:Number = -(aX * acX + aY * acY); |
|---|
| 125 |
var td:Number = (cX * acX + cY * acY); |
|---|
| 126 |
//float32 un = -b2Dot(b, bc), ud = b2Dot(c, bc); |
|---|
| 127 |
var un:Number = -(bX * bcX + bY * bcY); |
|---|
| 128 |
var ud:Number = (cX * bcX + cY * bcY); |
|---|
| 129 |
|
|---|
| 130 |
// In vertex c region? |
|---|
| 131 |
if (td <= 0.0 && ud <= 0.0) |
|---|
| 132 |
{ |
|---|
| 133 |
// Single point |
|---|
| 134 |
//*x1 = p1s[2]; |
|---|
| 135 |
x1.SetV(p1s_2); |
|---|
| 136 |
//*x2 = p2s[2]; |
|---|
| 137 |
x2.SetV(p2s_2); |
|---|
| 138 |
//p1s[0] = p1s[2]; |
|---|
| 139 |
p1s_0.SetV(p1s_2); |
|---|
| 140 |
//p2s[0] = p2s[2]; |
|---|
| 141 |
p2s_0.SetV(p2s_2); |
|---|
| 142 |
points_0.SetV(points_2); |
|---|
| 143 |
return 1; |
|---|
| 144 |
} |
|---|
| 145 |
|
|---|
| 146 |
// Should not be in vertex a or b region. |
|---|
| 147 |
//b2Settings.b2Assert(sn > 0.0 || tn > 0.0); |
|---|
| 148 |
//b2Settings.b2Assert(sd > 0.0 || un > 0.0); |
|---|
| 149 |
|
|---|
| 150 |
//float32 n = b2Cross(ab, ac); |
|---|
| 151 |
var n:Number = abX * acY - abY * acX; |
|---|
| 152 |
|
|---|
| 153 |
// Should not be in edge ab region. |
|---|
| 154 |
//float32 vc = n * b2Cross(a, b); |
|---|
| 155 |
var vc:Number = n * (aX * bY - aY * bX); |
|---|
| 156 |
//b2Settings.b2Assert(vc > 0.0 || sn > 0.0 || sd > 0.0); |
|---|
| 157 |
var lambda:Number; |
|---|
| 158 |
|
|---|
| 159 |
// In edge bc region? |
|---|
| 160 |
//float32 va = n * b2Cross(b, c); |
|---|
| 161 |
var va:Number = n * (bX * cY - bY * cX); |
|---|
| 162 |
if (va <= 0.0 && un >= 0.0 && ud >= 0.0 && (un+ud) > 0.0) |
|---|
| 163 |
{ |
|---|
| 164 |
//b2Settings.b2Assert(un + ud > 0.0); |
|---|
| 165 |
|
|---|
| 166 |
//float32 lambda = un / (un + ud); |
|---|
| 167 |
lambda = un / (un + ud); |
|---|
| 168 |
//*x1 = p1s[1] + lambda * (p1s[2] - p1s[1]); |
|---|
| 169 |
x1.x = p1s_1.x + lambda * (p1s_2.x - p1s_1.x); |
|---|
| 170 |
x1.y = p1s_1.y + lambda * (p1s_2.y - p1s_1.y); |
|---|
| 171 |
//*x2 = p2s[1] + lambda * (p2s[2] - p2s[1]); |
|---|
| 172 |
x2.x = p2s_1.x + lambda * (p2s_2.x - p2s_1.x); |
|---|
| 173 |
x2.y = p2s_1.y + lambda * (p2s_2.y - p2s_1.y); |
|---|
| 174 |
//p1s[0] = p1s[2]; |
|---|
| 175 |
p1s_0.SetV(p1s_2); |
|---|
| 176 |
//p2s[0] = p2s[2]; |
|---|
| 177 |
p2s_0.SetV(p2s_2); |
|---|
| 178 |
//points[0] = points[2]; |
|---|
| 179 |
points_0.SetV(points_2); |
|---|
| 180 |
return 2; |
|---|
| 181 |
} |
|---|
| 182 |
|
|---|
| 183 |
// In edge ac region? |
|---|
| 184 |
//float32 vb = n * b2Cross(c, a); |
|---|
| 185 |
var vb:Number = n * (cX * aY - cY * aX); |
|---|
| 186 |
if (vb <= 0.0 && tn >= 0.0 && td >= 0.0 && (tn+td) > 0.0) |
|---|
| 187 |
{ |
|---|
| 188 |
//b2Settings.b2Assert(tn + td > 0.0); |
|---|
| 189 |
|
|---|
| 190 |
//float32 lambda = tn / (tn + td); |
|---|
| 191 |
lambda = tn / (tn + td); |
|---|
| 192 |
//*x1 = p1s[0] + lambda * (p1s[2] - p1s[0]); |
|---|
| 193 |
x1.x = p1s_0.x + lambda * (p1s_2.x - p1s_0.x); |
|---|
| 194 |
x1.y = p1s_0.y + lambda * (p1s_2.y - p1s_0.y); |
|---|
| 195 |
//*x2 = p2s[0] + lambda * (p2s[2] - p2s[0]); |
|---|
| 196 |
x2.x = p2s_0.x + lambda * (p2s_2.x - p2s_0.x); |
|---|
| 197 |
x2.y = p2s_0.y + lambda * (p2s_2.y - p2s_0.y); |
|---|
| 198 |
//p1s[1] = p1s[2]; |
|---|
| 199 |
p1s_1.SetV(p1s_2); |
|---|
| 200 |
//p2s[1] = p2s[2]; |
|---|
| 201 |
p2s_1.SetV(p2s_2); |
|---|
| 202 |
//points[1] = points[2]; |
|---|
| 203 |
points_1.SetV(points_2); |
|---|
| 204 |
return 2; |
|---|
| 205 |
} |
|---|
| 206 |
|
|---|
| 207 |
// Inside the triangle, compute barycentric coordinates |
|---|
| 208 |
//float32 denom = va + vb + vc; |
|---|
| 209 |
var denom:Number = va + vb + vc; |
|---|
| 210 |
//b2Settings.b2Assert(denom > 0.0); |
|---|
| 211 |
denom = 1.0 / denom; |
|---|
| 212 |
//float32 u = va * denom; |
|---|
| 213 |
var u:Number = va * denom; |
|---|
| 214 |
//float32 v = vb * denom; |
|---|
| 215 |
var v:Number = vb * denom; |
|---|
| 216 |
//float32 w = 1.0f - u - v; |
|---|
| 217 |
var w:Number = 1.0 - u - v; |
|---|
| 218 |
//*x1 = u * p1s[0] + v * p1s[1] + w * p1s[2]; |
|---|
| 219 |
x1.x = u * p1s_0.x + v * p1s_1.x + w * p1s_2.x; |
|---|
| 220 |
x1.y = u * p1s_0.y + v * p1s_1.y + w * p1s_2.y; |
|---|
| 221 |
//*x2 = u * p2s[0] + v * p2s[1] + w * p2s[2]; |
|---|
| 222 |
x2.x = u * p2s_0.x + v * p2s_1.x + w * p2s_2.x; |
|---|
| 223 |
x2.y = u * p2s_0.y + v * p2s_1.y + w * p2s_2.y; |
|---|
| 224 |
return 3; |
|---|
| 225 |
} |
|---|
| 226 |
|
|---|
| 227 |
static public function InPoints(w:b2Vec2, points:Array, pointCount:int):Boolean |
|---|
| 228 |
{ |
|---|
| 229 |
const k_tolerance:Number = 100.0 * Number.MIN_VALUE; |
|---|
| 230 |
for (var i:int = 0; i < pointCount; ++i) |
|---|
| 231 |
{ |
|---|
| 232 |
var points_i:b2Vec2 = points[i]; |
|---|
| 233 |
//b2Vec2 d = b2Abs(w - points[i]); |
|---|
| 234 |
var dX:Number = Math.abs(w.x - points_i.x); |
|---|
| 235 |
var dY:Number = Math.abs(w.y - points_i.y); |
|---|
| 236 |
//b2Vec2 m = b2Max(b2Abs(w), b2Abs(points[i])); |
|---|
| 237 |
var mX:Number = Math.max(Math.abs(w.x), Math.abs(points_i.x)); |
|---|
| 238 |
var mY:Number = Math.max(Math.abs(w.y), Math.abs(points_i.y)); |
|---|
| 239 |
|
|---|
| 240 |
if (dX < k_tolerance * (mX + 1.0) && |
|---|
| 241 |
dY < k_tolerance * (mY + 1.0)){ |
|---|
| 242 |
return true; |
|---|
| 243 |
} |
|---|
| 244 |
} |
|---|
| 245 |
|
|---|
| 246 |
return false; |
|---|
| 247 |
} |
|---|
| 248 |
|
|---|
| 249 |
// |
|---|
| 250 |
static private var s_p1s:Array = [new b2Vec2(), new b2Vec2(), new b2Vec2()]; |
|---|
| 251 |
static private var s_p2s:Array = [new b2Vec2(), new b2Vec2(), new b2Vec2()]; |
|---|
| 252 |
static private var s_points:Array = [new b2Vec2(), new b2Vec2(), new b2Vec2()]; |
|---|
| 253 |
// |
|---|
| 254 |
|
|---|
| 255 |
static public function DistanceGeneric(x1:b2Vec2, x2:b2Vec2, |
|---|
| 256 |
shape1:*, xf1:b2XForm, |
|---|
| 257 |
shape2:*, xf2:b2XForm):Number |
|---|
| 258 |
{ |
|---|
| 259 |
var tVec: b2Vec2; |
|---|
| 260 |
|
|---|
| 261 |
//b2Vec2 p1s[3], p2s[3]; |
|---|
| 262 |
var p1s:Array = s_p1s; |
|---|
| 263 |
var p2s:Array = s_p2s; |
|---|
| 264 |
//b2Vec2 points[3]; |
|---|
| 265 |
var points:Array = s_points; |
|---|
| 266 |
//int32 pointCount = 0; |
|---|
| 267 |
var pointCount:int = 0; |
|---|
| 268 |
|
|---|
| 269 |
//*x1 = shape1->GetFirstVertex(xf1); |
|---|
| 270 |
x1.SetV(shape1.GetFirstVertex(xf1)); |
|---|
| 271 |
//*x2 = shape2->GetFirstVertex(xf2); |
|---|
| 272 |
x2.SetV(shape2.GetFirstVertex(xf2)); |
|---|
| 273 |
|
|---|
| 274 |
var vSqr:Number = 0.0; |
|---|
| 275 |
const maxIterations:int = 20; |
|---|
| 276 |
for (var iter:int = 0; iter < maxIterations; ++iter) |
|---|
| 277 |
{ |
|---|
| 278 |
//b2Vec2 v = *x2 - *x1; |
|---|
| 279 |
var vX:Number = x2.x - x1.x; |
|---|
| 280 |
var vY:Number = x2.y - x1.y; |
|---|
| 281 |
//b2Vec2 w1 = shape1->Support(xf1, v); |
|---|
| 282 |
var w1:b2Vec2 = shape1.Support(xf1, vX, vY); |
|---|
| 283 |
//b2Vec2 w2 = shape2->Support(xf2, -v); |
|---|
| 284 |
var w2:b2Vec2 = shape2.Support(xf2, -vX, -vY); |
|---|
| 285 |
//float32 vSqr = b2Dot(v, v); |
|---|
| 286 |
vSqr = (vX*vX + vY*vY); |
|---|
| 287 |
//b2Vec2 w = w2 - w1; |
|---|
| 288 |
var wX:Number = w2.x - w1.x; |
|---|
| 289 |
var wY:Number = w2.y - w1.y; |
|---|
| 290 |
//float32 vw = b2Dot(v, w); |
|---|
| 291 |
var vw:Number = (vX*wX + vY*wY); |
|---|
| 292 |
//if (vSqr - b2Dot(v, w) <= 0.01f * vSqr) // or w in points |
|---|
| 293 |
if (vSqr - vw <= 0.01 * vSqr) // or w in points |
|---|
| 294 |
{ |
|---|
| 295 |
if (pointCount == 0) |
|---|
| 296 |
{ |
|---|
| 297 |
//*x1 = w1; |
|---|
| 298 |
x1.SetV(w1); |
|---|
| 299 |
//*x2 = w2; |
|---|
| 300 |
x2.SetV(w2); |
|---|
| 301 |
} |
|---|
| 302 |
g_GJK_Iterations = iter; |
|---|
| 303 |
return Math.sqrt(vSqr); |
|---|
| 304 |
} |
|---|
| 305 |
|
|---|
| 306 |
switch (pointCount) |
|---|
| 307 |
{ |
|---|
| 308 |
case 0: |
|---|
| 309 |
//p1s[0] = w1; |
|---|
| 310 |
tVec = p1s[0]; |
|---|
| 311 |
tVec.SetV(w1); |
|---|
| 312 |
//p2s[0] = w2; |
|---|
| 313 |
tVec = p2s[0]; |
|---|
| 314 |
tVec.SetV(w2); |
|---|
| 315 |
//points[0] = w; |
|---|
| 316 |
tVec = points[0]; |
|---|
| 317 |
tVec.x = wX; |
|---|
| 318 |
tVec.y = wY; |
|---|
| 319 |
//*x1 = p1s[0]; |
|---|
| 320 |
x1.SetV(p1s[0]); |
|---|
| 321 |
//*x2 = p2s[0]; |
|---|
| 322 |
x2.SetV(p2s[0]); |
|---|
| 323 |
++pointCount; |
|---|
| 324 |
break; |
|---|
| 325 |
|
|---|
| 326 |
case 1: |
|---|
| 327 |
//p1s[1] = w1; |
|---|
| 328 |
tVec = p1s[1]; |
|---|
| 329 |
tVec.SetV(w1); |
|---|
| 330 |
//p2s[1] = w2; |
|---|
| 331 |
tVec = p2s[1]; |
|---|
| 332 |
tVec.SetV(w2); |
|---|
| 333 |
//points[1] = w; |
|---|
| 334 |
tVec = points[1]; |
|---|
| 335 |
tVec.x = wX; |
|---|
| 336 |
tVec.y = wY; |
|---|
| 337 |
pointCount = ProcessTwo(x1, x2, p1s, p2s, points); |
|---|
| 338 |
break; |
|---|
| 339 |
|
|---|
| 340 |
case 2: |
|---|
| 341 |
//p1s[2] = w1; |
|---|
| 342 |
tVec = p1s[2]; |
|---|
| 343 |
tVec.SetV(w1); |
|---|
| 344 |
//p2s[2] = w2; |
|---|
| 345 |
tVec = p2s[2]; |
|---|
| 346 |
tVec.SetV(w2); |
|---|
| 347 |
//points[2] = w; |
|---|
| 348 |
tVec = points[2]; |
|---|
| 349 |
tVec.x = wX; |
|---|
| 350 |
tVec.y = wY; |
|---|
| 351 |
pointCount = ProcessThree(x1, x2, p1s, p2s, points); |
|---|
| 352 |
break; |
|---|
| 353 |
} |
|---|
| 354 |
|
|---|
| 355 |
// If we have three points, then the origin is in the corresponding triangle. |
|---|
| 356 |
if (pointCount == 3) |
|---|
| 357 |
{ |
|---|
| 358 |
g_GJK_Iterations = iter; |
|---|
| 359 |
return 0.0; |
|---|
| 360 |
} |
|---|
| 361 |
|
|---|
| 362 |
//float32 maxSqr = -FLT_MAX; |
|---|
| 363 |
var maxSqr:Number = -Number.MAX_VALUE; |
|---|
| 364 |
for (var i:int = 0; i < pointCount; ++i) |
|---|
| 365 |
{ |
|---|
| 366 |
//maxSqr = b2Math.b2Max(maxSqr, b2Dot(points[i], points[i])); |
|---|
| 367 |
tVec = points[i]; |
|---|
| 368 |
maxSqr = b2Math.b2Max(maxSqr, (tVec.x*tVec.x + tVec.y*tVec.y)); |
|---|
| 369 |
} |
|---|
| 370 |
|
|---|
| 371 |
if (pointCount == 3 || vSqr <= 100.0 * Number.MIN_VALUE * maxSqr) |
|---|
| 372 |
{ |
|---|
| 373 |
g_GJK_Iterations = iter; |
|---|
| 374 |
//v = *x2 - *x1; |
|---|
| 375 |
vX = x2.x - x1.x; |
|---|
| 376 |
vY = x2.y - x1.y; |
|---|
| 377 |
//vSqr = b2Dot(v, v); |
|---|
| 378 |
vSqr = (vX*vX + vY*vY); |
|---|
| 379 |
return Math.sqrt(vSqr); |
|---|
| 380 |
} |
|---|
| 381 |
} |
|---|
| 382 |
|
|---|
| 383 |
g_GJK_Iterations = maxIterations; |
|---|
| 384 |
return Math.sqrt(vSqr); |
|---|
| 385 |
} |
|---|
| 386 |
|
|---|
| 387 |
|
|---|
| 388 |
static public function DistanceCC( |
|---|
| 389 |
x1:b2Vec2, x2:b2Vec2, |
|---|
| 390 |
circle1:b2CircleShape, xf1:b2XForm, |
|---|
| 391 |
circle2:b2CircleShape, xf2:b2XForm) : Number |
|---|
| 392 |
{ |
|---|
| 393 |
var tMat:b2Mat22; |
|---|
| 394 |
var tVec:b2Vec2; |
|---|
| 395 |
//b2Vec2 p1 = b2Mul(xf1, circle1->m_localPosition); |
|---|
| 396 |
tMat = xf1.R; |
|---|
| 397 |
tVec = circle1.m_localPosition; |
|---|
| 398 |
var p1X:Number = xf1.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); |
|---|
| 399 |
var p1Y:Number = xf1.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); |
|---|
| 400 |
//b2Vec2 p2 = b2Mul(xf2, circle2->m_localPosition); |
|---|
| 401 |
tMat = xf2.R; |
|---|
| 402 |
tVec = circle2.m_localPosition; |
|---|
| 403 |
var p2X:Number = xf2.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); |
|---|
| 404 |
var p2Y:Number = xf2.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); |
|---|
| 405 |
|
|---|
| 406 |
//b2Vec2 d = p2 - p1; |
|---|
| 407 |
var dX:Number = p2X - p1X; |
|---|
| 408 |
var dY:Number = p2Y - p1Y; |
|---|
| 409 |
var dSqr:Number = (dX*dX + dY*dY); |
|---|
| 410 |
var r1:Number = circle1.m_radius - b2Settings.b2_toiSlop; |
|---|
| 411 |
var r2:Number = circle2.m_radius - b2Settings.b2_toiSlop; |
|---|
| 412 |
var r:Number = r1 + r2; |
|---|
| 413 |
if (dSqr > r * r) |
|---|
| 414 |
{ |
|---|
| 415 |
//var dLen:Number = d.Normalize(); |
|---|
| 416 |
var dLen:Number = Math.sqrt(dSqr); |
|---|
| 417 |
dX /= dLen; |
|---|
| 418 |
dY /= dLen; |
|---|
| 419 |
var distance:Number = dLen - r; |
|---|
| 420 |
//*x1 = p1 + r1 * d; |
|---|
| 421 |
x1.x = p1X + r1 * dX; |
|---|
| 422 |
x1.y = p1Y + r1 * dY; |
|---|
| 423 |
//*x2 = p2 - r2 * d; |
|---|
| 424 |
x2.x = p2X - r2 * dX; |
|---|
| 425 |
x2.y = p2Y - r2 * dY; |
|---|
| 426 |
return distance; |
|---|
| 427 |
} |
|---|
| 428 |
else if (dSqr > Number.MIN_VALUE * Number.MIN_VALUE) |
|---|
| 429 |
{ |
|---|
| 430 |
//d.Normalize(); |
|---|
| 431 |
dLen = Math.sqrt(dSqr); |
|---|
| 432 |
dX /= dLen; |
|---|
| 433 |
dY /= dLen; |
|---|
| 434 |
//*x1 = p1 + r1 * d; |
|---|
| 435 |
x1.x = p1X + r1 * dX; |
|---|
| 436 |
x1.y = p1Y + r1 * dY; |
|---|
| 437 |
//*x2 = *x1; |
|---|
| 438 |
x2.x = x1.x; |
|---|
| 439 |
x2.y = x1.y; |
|---|
| 440 |
return 0.0; |
|---|
| 441 |
} |
|---|
| 442 |
|
|---|
| 443 |
//*x1 = p1; |
|---|
| 444 |
x1.x = p1X; |
|---|
| 445 |
x1.y = p1Y; |
|---|
| 446 |
//*x2 = *x1; |
|---|
| 447 |
x2.x = x1.x; |
|---|
| 448 |
x2.y = x1.y; |
|---|
| 449 |
return 0.0; |
|---|
| 450 |
} |
|---|
| 451 |
|
|---|
| 452 |
|
|---|
| 453 |
|
|---|
| 454 |
// GJK is more robust with polygon-vs-point than polygon-vs-circle. |
|---|
| 455 |
// So we convert polygon-vs-circle to polygon-vs-point. |
|---|
| 456 |
static private var gPoint:b2Point = new b2Point(); |
|---|
| 457 |
/// |
|---|
| 458 |
static public function DistancePC( |
|---|
| 459 |
x1:b2Vec2, x2:b2Vec2, |
|---|
| 460 |
polygon:b2PolygonShape, xf1:b2XForm, |
|---|
| 461 |
circle:b2CircleShape, xf2:b2XForm) : Number |
|---|
| 462 |
{ |
|---|
| 463 |
|
|---|
| 464 |
var tMat:b2Mat22; |
|---|
| 465 |
var tVec:b2Vec2; |
|---|
| 466 |
|
|---|
| 467 |
var point:b2Point = gPoint; |
|---|
| 468 |
//point.p = b2Mul(xf2, circle->m_localPosition); |
|---|
| 469 |
tVec = circle.m_localPosition; |
|---|
| 470 |
tMat = xf2.R; |
|---|
| 471 |
point.p.x = xf2.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); |
|---|
| 472 |
point.p.y = xf2.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); |
|---|
| 473 |
|
|---|
| 474 |
// Create variation of function to replace template |
|---|
| 475 |
var distance:Number = DistanceGeneric(x1, x2, polygon, xf1, point, b2Math.b2XForm_identity); |
|---|
| 476 |
|
|---|
| 477 |
var r:Number = circle.m_radius - b2Settings.b2_toiSlop; |
|---|
| 478 |
|
|---|
| 479 |
if (distance > r) |
|---|
| 480 |
{ |
|---|
| 481 |
distance -= r; |
|---|
| 482 |
//b2Vec2 d = *x2 - *x1; |
|---|
| 483 |
var dX:Number = x2.x - x1.x; |
|---|
| 484 |
var dY:Number = x2.y - x1.y; |
|---|
| 485 |
//d.Normalize(); |
|---|
| 486 |
var dLen:Number = Math.sqrt(dX*dX + dY*dY); |
|---|
| 487 |
dX /= dLen; |
|---|
| 488 |
dY /= dLen; |
|---|
| 489 |
//*x2 -= r * d; |
|---|
| 490 |
x2.x -= r * dX; |
|---|
| 491 |
x2.y -= r * dY; |
|---|
| 492 |
} |
|---|
| 493 |
else |
|---|
| 494 |
{ |
|---|
| 495 |
distance = 0.0; |
|---|
| 496 |
//*x2 = *x1; |
|---|
| 497 |
x2.x = x1.x; |
|---|
| 498 |
x2.y = x1.y; |
|---|
| 499 |
} |
|---|
| 500 |
|
|---|
| 501 |
return distance; |
|---|
| 502 |
} |
|---|
| 503 |
|
|---|
| 504 |
|
|---|
| 505 |
static public function Distance(x1:b2Vec2, x2:b2Vec2, |
|---|
| 506 |
shape1:b2Shape, xf1:b2XForm, |
|---|
| 507 |
shape2:b2Shape, xf2:b2XForm) : Number |
|---|
| 508 |
{ |
|---|
| 509 |
//b2ShapeType type1 = shape1->GetType(); |
|---|
| 510 |
var type1:int = shape1.m_type; |
|---|
| 511 |
//b2ShapeType type2 = shape2->GetType(); |
|---|
| 512 |
var type2:int = shape2.m_type; |
|---|
| 513 |
|
|---|
| 514 |
if (type1 == b2Shape.e_circleShape && type2 == b2Shape.e_circleShape) |
|---|
| 515 |
{ |
|---|
| 516 |
//return DistanceCC(x1, x2, (b2CircleShape*)shape1, xf1, (b2CircleShape*)shape2, xf2); |
|---|
| 517 |
return DistanceCC(x1, x2, shape1 as b2CircleShape, xf1, shape2 as b2CircleShape, xf2); |
|---|
| 518 |
} |
|---|
| 519 |
|
|---|
| 520 |
if (type1 == b2Shape.e_polygonShape && type2 == b2Shape.e_circleShape) |
|---|
| 521 |
{ |
|---|
| 522 |
//return DistancePC(x1, x2, (b2PolygonShape*)shape1, xf1, (b2CircleShape*)shape2, xf2); |
|---|
| 523 |
return DistancePC(x1, x2, shape1 as b2PolygonShape, xf1, shape2 as b2CircleShape, xf2); |
|---|
| 524 |
} |
|---|
| 525 |
|
|---|
| 526 |
if (type1 == b2Shape.e_circleShape && type2 == b2Shape.e_polygonShape) |
|---|
| 527 |
{ |
|---|
| 528 |
return DistancePC(x2, x1, shape2 as b2PolygonShape, xf2, shape1 as b2CircleShape, xf1); |
|---|
| 529 |
} |
|---|
| 530 |
|
|---|
| 531 |
if (type1 == b2Shape.e_polygonShape && type2 == b2Shape.e_polygonShape) |
|---|
| 532 |
{ |
|---|
| 533 |
return DistanceGeneric(x1, x2, shape1 as b2PolygonShape, xf1, shape2 as b2PolygonShape, xf2); |
|---|
| 534 |
} |
|---|
| 535 |
|
|---|
| 536 |
return 0.0; |
|---|
| 537 |
} |
|---|
| 538 |
|
|---|
| 539 |
|
|---|
| 540 |
|
|---|
| 541 |
static public var g_GJK_Iterations:int = 0; |
|---|
| 542 |
|
|---|
| 543 |
|
|---|
| 544 |
|
|---|
| 545 |
}; |
|---|
| 546 |
|
|---|
| 547 |
|
|---|
| 548 |
} |
|---|