Войти
ЗаВел

2D коллизии

Автор:

Два дня ломал голову над тем, как проще и эффективнее реализовать обнаружение столкновений объектов на плоскости. Возможно, кому то покажется это странным, ведь есть уже гора готовых решений... Но я лёгкий путей никогда не искал.
Под конец второго дня придумал таки странную штуку. По трудоёмкости сравнима с построением AABB, если не считать 3~4 (по вкусу) вычислений квадратного корня. Пока-что прекрасно работает с выпуклой геометрией, но кажется мне, что один маленький хак может расширить "сферу влияния".

пока что выложу тот кусочек кода, что я использую в своих экспериментах для отрисовки заколлиженных точек

Pen p = new Pen(Color.White);
                PointF[] ps = figures[0];
                float x = 0;
                for (; x < ClientSize.Width; x++)
                {
                    for (float y = 0; y < ClientSize.Height; y++)
                    {
                        double w = 0.0;
                        for (int i = 0; i < ps.Length; i++)
                        {
                            PointF p0 = ps[(ps.Length + i - 1) % ps.Length];
                            PointF p1 = ps[i];
                            PointF p2 = ps[(i + 1) % ps.Length];
                            float vx = x - p1.X;
                            float vy = y - p1.Y;
                            float vx0 = p0.X - p1.X;
                            float vy0 = p0.Y - p1.Y;
                            float vx1 = p2.X - p1.X;
                            float vy1 = p2.Y - p1.Y;
                            double d = Math.Sqrt(sqr(vx) + sqr(vy));
                            double d0 = Math.Sqrt(sqr(vx0) + sqr(vy0));
                            double d1 = Math.Sqrt(sqr(vx1) + sqr(vy1));
                            double nx = (vx * vy1 - vy * vx1) / (d1 * d);
                            double ny = (vy * vx0 - vx * vy0) / (d0 * d);        
                            if (nx < 0.0 || ny < 0.0)
                            {
                                w = 0.0;
                                break;
                            }
                            d = Math.Sqrt(sqr(nx) + sqr(ny));                    
                            w += (nx + ny) / d;
                        }
                        w /= ps.Length;
                        w *= 110;
                        if (w >= 0.0)
                        {
                            if (w > 255.0)
                                w = 255.0;
                            p.Color = Color.FromArgb((int)(w), (int)(w), (int)(w));
                            gbuf.Graphics.DrawLine(p, x, y, x + 1, y);
                        }
                    }
                }
                p.Dispose();

#2D, #коллизии, #коллизия, #столкновение

2 декабря 2012