OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2010, Google Inc. | 2 * Copyright 2010, Google Inc. |
3 * All rights reserved. | 3 * All rights reserved. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions are | 6 * modification, are permitted provided that the following conditions are |
7 * met: | 7 * met: |
8 * | 8 * |
9 * * Redistributions of source code must retain the above copyright | 9 * * Redistributions of source code must retain the above copyright |
10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
42 int Orientation(float x1, float y1, | 42 int Orientation(float x1, float y1, |
43 float x2, float y2, | 43 float x2, float y2, |
44 float x3, float y3) { | 44 float x3, float y3) { |
45 // p1 = (x1, y1) | 45 // p1 = (x1, y1) |
46 // p2 = (x2, y2) | 46 // p2 = (x2, y2) |
47 // p3 = (x3, y3) | 47 // p3 = (x3, y3) |
48 float cross_product = (y2 - y1) * (x3 - x2) - (y3 - y2) * (x2 - x1); | 48 float cross_product = (y2 - y1) * (x3 - x2) - (y3 - y2) * (x2 - x1); |
49 return (cross_product < 0.0f) ? -1 : ((cross_product > 0.0f) ? 1 : 0); | 49 return (cross_product < 0.0f) ? -1 : ((cross_product > 0.0f) ? 1 : 0); |
50 } | 50 } |
51 | 51 |
| 52 bool EdgeEdgeTest(float ax, float ay, |
| 53 float v0x, float v0y, |
| 54 float u0x, float u0y, |
| 55 float u1x, float u1y) { |
| 56 // This edge to edge test is based on Franlin Antonio's gem: "Faster |
| 57 // Line Segment Intersection", in Graphics Gems III, pp. 199-202. |
| 58 float bx = u0x - u1x; |
| 59 float by = u0y - u1y; |
| 60 float cx = v0x - u0x; |
| 61 float cy = v0y - u0y; |
| 62 float f = ay * bx - ax * by; |
| 63 float d = by * cx - bx * cy; |
| 64 if ((f > 0 && d >= 0 && d <= f) || (f < 0 && d <= 0 && d >= f)) { |
| 65 float e = ax * cy - ay * cx; |
| 66 |
| 67 // This additional test avoids reporting coincident edges, which |
| 68 // is the behavior we want. |
| 69 if (ApproxEqual(e, 0) || ApproxEqual(f, 0) || ApproxEqual(e, f)) { |
| 70 return false; |
| 71 } |
| 72 |
| 73 if (f > 0) { |
| 74 return e >= 0 && e <= f; |
| 75 } else { |
| 76 return e <= 0 && e >= f; |
| 77 } |
| 78 } |
| 79 return false; |
| 80 } |
| 81 |
| 82 bool EdgeAgainstTriEdges(float v0x, float v0y, |
| 83 float v1x, float v1y, |
| 84 float u0x, float u0y, |
| 85 float u1x, float u1y, |
| 86 float u2x, float u2y) { |
| 87 float ax, ay; |
| 88 ax = v1x - v0x; |
| 89 ay = v1y - v0y; |
| 90 // Test edge u0, u1 against v0, v1. |
| 91 if (EdgeEdgeTest(ax, ay, v0x, v0y, u0x, u0y, u1x, u1y)) { |
| 92 return true; |
| 93 } |
| 94 // Test edge u1, u2 against v0, v1. |
| 95 if (EdgeEdgeTest(ax, ay, v0x, v0y, u1x, u1y, u2x, u2y)) { |
| 96 return true; |
| 97 } |
| 98 // Test edge u2, u1 against v0, v1. |
| 99 if (EdgeEdgeTest(ax, ay, v0x, v0y, u2x, u2y, u0x, u0y)) { |
| 100 return true; |
| 101 } |
| 102 return false; |
| 103 } |
| 104 |
52 } // anonymous namespace | 105 } // anonymous namespace |
53 | 106 |
54 bool LinesIntersect(float p1x, float p1y, | 107 bool LinesIntersect(float p1x, float p1y, |
55 float q1x, float q1y, | 108 float q1x, float q1y, |
56 float p2x, float p2y, | 109 float p2x, float p2y, |
57 float q2x, float q2y) { | 110 float q2x, float q2y) { |
58 return ((Orientation(p1x, p1y, q1x, q1y, p2x, p2y) != | 111 return ((Orientation(p1x, p1y, q1x, q1y, p2x, p2y) != |
59 Orientation(p1x, p1y, q1x, q1y, q2x, q2y)) && | 112 Orientation(p1x, p1y, q1x, q1y, q2x, q2y)) && |
60 (Orientation(p2x, p2y, q2x, q2y, p1x, p1y) != | 113 (Orientation(p2x, p2y, q2x, q2y, p1x, p1y) != |
61 Orientation(p2x, p2y, q2x, q2y, q1x, q1y))); | 114 Orientation(p2x, p2y, q2x, q2y, q1x, q1y))); |
(...skipping 22 matching lines...) Expand all Loading... |
84 return false; | 137 return false; |
85 } | 138 } |
86 // Compute | 139 // Compute |
87 float invDenom = 1.0f / denom; | 140 float invDenom = 1.0f / denom; |
88 float u = (dot11 * dot02 - dot01 * dot12) * invDenom; | 141 float u = (dot11 * dot02 - dot01 * dot12) * invDenom; |
89 float v = (dot00 * dot12 - dot01 * dot02) * invDenom; | 142 float v = (dot00 * dot12 - dot01 * dot02) * invDenom; |
90 | 143 |
91 return (u > 0.0f) && (v > 0.0f) && (u + v < 1.0f); | 144 return (u > 0.0f) && (v > 0.0f) && (u + v < 1.0f); |
92 } | 145 } |
93 | 146 |
| 147 bool TrianglesOverlap(float a1x, float a1y, |
| 148 float b1x, float b1y, |
| 149 float c1x, float c1y, |
| 150 float a2x, float a2y, |
| 151 float b2x, float b2y, |
| 152 float c2x, float c2y) { |
| 153 // Derived from coplanar_tri_tri() at |
| 154 // http://jgt.akpeters.com/papers/ShenHengTang03/tri_tri.html , |
| 155 // simplified for the 2D case and modified so that overlapping edges |
| 156 // do not report overlapping triangles. |
| 157 |
| 158 // Test all edges of triangle 1 against the edges of triangle 2. |
| 159 if (EdgeAgainstTriEdges(a1x, a1y, b1x, b1y, a2x, a2y, b2x, b2y, c2x, c2y)) |
| 160 return true; |
| 161 if (EdgeAgainstTriEdges(b1x, b1y, c1x, c1y, a2x, a2y, b2x, b2y, c2x, c2y)) |
| 162 return true; |
| 163 if (EdgeAgainstTriEdges(c1x, c1y, a1x, a1y, a2x, a2y, b2x, b2y, c2x, c2y)) |
| 164 return true; |
| 165 // Finally, test if tri1 is totally contained in tri2 or vice versa. |
| 166 if (PointInTriangle(a1x, a1y, a2x, a2y, b2x, b2y, c2x, c2y)) |
| 167 return true; |
| 168 if (PointInTriangle(a2x, a2y, a1x, a1y, b1x, b1y, c1x, c1y)) |
| 169 return true; |
| 170 |
| 171 // Because we define that triangles sharing a vertex or edge don't |
| 172 // overlap, we must perform additional point-in-triangle tests to |
| 173 // see whether one triangle is contained in the other. |
| 174 if (PointInTriangle(b1x, b1y, a2x, a2y, b2x, b2y, c2x, c2y)) |
| 175 return true; |
| 176 if (PointInTriangle(c1x, c1y, a2x, a2y, b2x, b2y, c2x, c2y)) |
| 177 return true; |
| 178 if (PointInTriangle(b2x, b2y, a1x, a1y, b1x, b1y, c1x, c1y)) |
| 179 return true; |
| 180 if (PointInTriangle(c2x, c2y, a1x, a1y, b1x, b1y, c1x, c1y)) |
| 181 return true; |
| 182 return false; |
| 183 } |
| 184 |
94 } // namespace cubic | 185 } // namespace cubic |
95 } // namespace gpu2d | 186 } // namespace gpu2d |
96 } // namespace o3d | 187 } // namespace o3d |
97 | 188 |
OLD | NEW |