247 | | |
248 | | fixed hw = halfSize.X; |
249 | | fixed hh = halfSize.Y; |
250 | | |
251 | | fixed au = a.Dot(u); |
252 | | fixed av = a.Dot(v); |
253 | | |
254 | | if (-hw <= au && au <= hw && -hh <= av && av <= hh) |
255 | | return false; // a is inside |
256 | | |
257 | | fixed bu = b.Dot(u); |
258 | | fixed bv = b.Dot(v); |
259 | | |
260 | | if (-hw <= bu && bu <= hw && -hh <= bv && bv <= hh) // TODO: isn't this subsumed by the next checks? |
261 | | return true; // a is outside, b is inside |
262 | | |
263 | | if ((au < -hw && bu < -hw) || (au > hw && bu > hw) || (av < -hh && bv < -hh) || (av > hh && bv > hh)) |
264 | | return false; // ab is entirely above/below/side the square |
265 | | |
266 | | CFixedVector2D abp = (b - a).Perpendicular(); |
267 | | fixed s0 = abp.Dot((u.Multiply(hw) + v.Multiply(hh)) - a); |
268 | | fixed s1 = abp.Dot((u.Multiply(hw) - v.Multiply(hh)) - a); |
269 | | fixed s2 = abp.Dot((-u.Multiply(hw) - v.Multiply(hh)) - a); |
270 | | fixed s3 = abp.Dot((-u.Multiply(hw) + v.Multiply(hh)) - a); |
271 | | if (s0.IsZero() || s1.IsZero() || s2.IsZero() || s3.IsZero()) |
272 | | return true; // ray intersects the corner |
273 | | |
274 | | bool sign = (s0 < fixed::Zero()); |
275 | | if ((s1 < fixed::Zero()) != sign || (s2 < fixed::Zero()) != sign || (s3 < fixed::Zero()) != sign) |
276 | | return true; // ray cuts through the square |
277 | | |
278 | | return false; |
| 243 | |
| 244 | return TestRaySquare(a, b, u, v, halfSize); |