00001
00002
00003
00004
00005
00006 namespace NewGamePhysics.Utilities
00007 {
00008 using System;
00009 using Microsoft.Xna.Framework;
00010
00014 public static class IntersectionTest
00015 {
00028 public static bool CircleInCircle2D(Vector2 centerA, double radiusA, Vector2 centerB, double radiusB)
00029 {
00030 if ((radiusA < 0.0) || (radiusB < 0.0))
00031 {
00032 return false;
00033 }
00034
00035 double dX = (double)(centerB.X - centerA.X);
00036 double dY = (double)(centerB.Y - centerA.Y);
00037 double d = Math.Sqrt(dX * dX + dY * dY);
00038
00039
00040 if (d > (radiusA + radiusB))
00041 {
00042 return false;
00043 }
00044
00045 return true;
00046 }
00047
00057 public static bool PointInPolygon2D(Vector2[] polygonVertex, Vector2 testVertex)
00058 {
00059 bool c = false;
00060 int nvert = polygonVertex.Length;
00061 if (nvert > 2)
00062 {
00063 int i, j;
00064 for (i = 0, j = nvert - 1; i < nvert; j = i++)
00065 {
00066 if (((polygonVertex[i].Y > testVertex.Y) != (polygonVertex[j].Y > testVertex.Y)) &&
00067 (testVertex.X < (polygonVertex[j].X - polygonVertex[i].X) *
00068 (testVertex.Y - polygonVertex[i].Y) /
00069 (polygonVertex[j].Y - polygonVertex[i].Y) + polygonVertex[i].X))
00070 {
00071 c = !c;
00072 }
00073 }
00074 }
00075
00076 return c;
00077 }
00078
00099 public static bool TriangleTriangleIntersect2D(
00100 Vector2 p1,
00101 Vector2 q1,
00102 Vector2 r1,
00103 Vector2 p2,
00104 Vector2 q2,
00105 Vector2 r2)
00106 {
00107 if (Orientation2D(p1, q1, r1) < 0.0f)
00108 {
00109 if (Orientation2D(p2, q2, r2) < 0.0f)
00110 {
00111 return CcwTriTriIntersection2D(p1, r1, q1, p2, r2, q2);
00112 }
00113 else
00114 {
00115 return CcwTriTriIntersection2D(p1, r1, q1, p2, q2, r2);
00116 }
00117 }
00118 else
00119 {
00120 if (Orientation2D(p2, q2, r2) < 0.0f)
00121 {
00122 return CcwTriTriIntersection2D(p1, q1, r1, p2, r2, q2);
00123 }
00124 else
00125 {
00126 return CcwTriTriIntersection2D(p1, q1, r1, p2, q2, r2);
00127 }
00128 }
00129 }
00130
00131
00142 private static bool CcwTriTriIntersection2D(
00143 Vector2 p1,
00144 Vector2 q1,
00145 Vector2 r1,
00146 Vector2 p2,
00147 Vector2 q2,
00148 Vector2 r2)
00149 {
00150 if (Orientation2D(p2, q2, p1) >= 0.0f)
00151 {
00152 if (Orientation2D(q2, r2, p1) >= 0.0f)
00153 {
00154 if (Orientation2D(r2, p2, p1) >= 0.0f)
00155 {
00156 return true;
00157 }
00158 else
00159 {
00160 return TestEdgeIntersection(p1, q1, r1, p2, q2, r2);
00161 }
00162 }
00163 else
00164 {
00165 if (Orientation2D(r2, p2, p1) >= 0.0f)
00166 {
00167 return TestEdgeIntersection(p1, q1, r1, r2, p2, q2);
00168 }
00169 else
00170 {
00171 return TestVertexIntersection2D(p1, q1, r1, p2, q2, r2);
00172 }
00173 }
00174 }
00175 else
00176 {
00177 if (Orientation2D(q2, r2, p1) >= 0.0f)
00178 {
00179 if (Orientation2D(r2, p2, p1) >= 0.0f)
00180 {
00181 return TestEdgeIntersection(p1, q1, r1, q2, r2, p2);
00182 }
00183 else
00184 {
00185 return TestVertexIntersection2D(p1, q1, r1, q2, r2, p2);
00186 }
00187 }
00188 else
00189 {
00190 return TestVertexIntersection2D(p1, q1, r1, r2, p2, q2);
00191 }
00192 }
00193 }
00194
00202 private static float Orientation2D(Vector2 p, Vector2 q, Vector2 r)
00203 {
00204 return ((p.X - r.X) * (q.Y - r.Y) - (p.Y - r.Y) * (q.X - r.X));
00205 }
00206
00217 private static bool TestEdgeIntersection(
00218 Vector2 p1,
00219 Vector2 q1,
00220 Vector2 r1,
00221 Vector2 p2,
00222 Vector2 q2,
00223 Vector2 r2)
00224 {
00225 if (Orientation2D(r2, p2, q1) >= 0.0f)
00226 {
00227 if (Orientation2D(p1, p2, q1) >= 0.0f)
00228 {
00229 if (Orientation2D(p1, q1, r2) >= 0.0f)
00230 {
00231 return true;
00232 }
00233 else
00234 {
00235 return false;
00236 }
00237 }
00238 else
00239 {
00240 if (Orientation2D(q1, r1, p2) >= 0.0f)
00241 {
00242 if (Orientation2D(r1, p1, p2) >= 0.0f)
00243 {
00244 return true;
00245 }
00246 else
00247 {
00248 return false;
00249 }
00250 }
00251 else
00252 {
00253 return false;
00254 }
00255 }
00256 }
00257 else
00258 {
00259 if (Orientation2D(r2, p2, r1) >= 0.0f)
00260 {
00261 if (Orientation2D(p1, p2, r1) >= 0.0f)
00262 {
00263 if (Orientation2D(p1, r1, r2) >= 0.0f)
00264 {
00265 return true;
00266 }
00267 else
00268 {
00269 if (Orientation2D(q1, r1, r2) >= 0.0f)
00270 {
00271 return true;
00272 }
00273 else
00274 {
00275 return false;
00276 }
00277 }
00278 }
00279 else
00280 {
00281 return false;
00282 }
00283 }
00284 else
00285 {
00286 return false;
00287 }
00288 }
00289 }
00290
00301 private static bool TestVertexIntersection2D(
00302 Vector2 p1,
00303 Vector2 q1,
00304 Vector2 r1,
00305 Vector2 p2,
00306 Vector2 q2,
00307 Vector2 r2)
00308 {
00309 if (Orientation2D(r2, p2, q1) >= 0.0f)
00310 {
00311 if (Orientation2D(r2, q2, q1) <= 0.0f)
00312 {
00313 if (Orientation2D(p1, p2, q1) > 0.0f)
00314 {
00315 if (Orientation2D(p1, q2, q1) <= 0.0f)
00316 {
00317 return true;
00318 }
00319 else
00320 {
00321 return false;
00322 }
00323 }
00324 else
00325 {
00326 if (Orientation2D(p1, p2, r1) >= 0.0f)
00327 {
00328 if (Orientation2D(q1, r1, p2) >= 0.0f)
00329 {
00330 return true;
00331 }
00332 else
00333 {
00334 return false;
00335 }
00336 }
00337 else
00338 {
00339 return false;
00340 }
00341 }
00342 }
00343 else
00344 {
00345 if (Orientation2D(p1, q2, q1) <= 0.0f)
00346 {
00347 if (Orientation2D(r2, q2, r1) <= 0.0f)
00348 {
00349 if (Orientation2D(q1, r1, q2) >= 0.0f)
00350 {
00351 return true;
00352 }
00353 else
00354 {
00355 return false;
00356 }
00357 }
00358 else
00359 {
00360 return false;
00361 }
00362 }
00363 else
00364 {
00365 return false;
00366 }
00367 }
00368 }
00369 else
00370 {
00371 if (Orientation2D(r2, p2, r1) >= 0.0f)
00372 {
00373 if (Orientation2D(q1, r1, r2) >= 0.0f)
00374 {
00375 if (Orientation2D(p1, p2, r1) >= 0.0f)
00376 {
00377 return true;
00378 }
00379 else
00380 {
00381 return false;
00382 }
00383 }
00384 else
00385 {
00386 if (Orientation2D(q1, r1, q2) >= 0.0f)
00387 {
00388 if (Orientation2D(r2, r1, q2) >= 0.0f)
00389 {
00390 return true;
00391 }
00392 else
00393 {
00394 return false;
00395 }
00396 }
00397 else
00398 {
00399 return false;
00400 }
00401 }
00402 }
00403 else
00404 {
00405 return false;
00406 }
00407 }
00408 }
00409 }
00410 }