Pole 2D Sprawdź, czy punkt przecina ciało

10

Czy istnieje sposób, aby sprawdzić, czy punkt przecina ciało?

Załóżmy na przykład, że na świecie jest ciało w pozycji (100,100).

Czy istnieje sposób sprawdzenia, czy punkt na (100,100) przecina to ciało?

Kolejny przykład dotyczy gry o nazwie „PHUN”. W PHUN możesz klikać i przeciągać ciała wokół. Jak sprawdziłbyś, czy punkt myszy przecina ciało?

xAustechx
źródło

Odpowiedzi:

5

Podobnie jak w przypadku odpowiedzi Colina, b2World.Query () jest przydatną funkcją, jeśli ustawisz aabb tak, aby obejmował tylko jeden punkt, możesz uzyskać listę obiektów, które mogą pokrywać się z tym punktem. Jednak ze względu na problemy z prędkością sprawdza tylko ramkę ograniczającą (AABB) pod kątem nakładania się, które nie zawsze jest całkowicie dokładne.

Aby dokładnie sprawdzić urządzenie (kształt, we starszych wersjach), użyj funkcji b2Fixture.TestPoint (). Ponieważ ciało może mieć wiele urządzeń, konieczne może być przejście przez całą listę, aby się upewnić. Łączenie tych 2 funkcji powinno umożliwić odtworzenie funkcjonalności Phun, jeśli chcesz.

Toeofdoom
źródło
2

Zobacz, b2QueryCallbackktóre urządzenia zawierają punkt i użyj, b2MouseJointaby obiekty podążały za myszą. Mam przykładowy kod, ale nie ma czasu, aby go teraz uprościć. Jeśli będziesz go potrzebować, mogę dostarczyć go później.

Colin Gislason
źródło
2

Jeśli masz punkt, o którym wiesz , że znajduje się wewnątrz kształtu, możesz przeciąć linię łączącą położenie myszy z tym punktem z granicą kształtu. Jeśli istnieje nieparzysta liczba skrzyżowań, oznacza to, że punkt jest w środku. Jeśli istnieje parzysta liczba skrzyżowań, oznacza to, że punkt znajduje się na zewnątrz.

alternatywny tekst
(źródło: co.uk )

Zielone kropki to lokalizacje myszy, czerwona to znany punkt wewnątrz kształtu.

Zdarzają się przypadki na krawędziach - jeśli linia łącząca punkty na przykład pokrywa się z krawędzią - ale to powinno zapewnić ci 90% drogi.

ChrisF
źródło
0

Wiem, że to pytanie jest stare, ale wydaje mi się, że brakuje w nim prostej odpowiedzi opartej na kodzie. Oto on:

    /// <summary>
    /// Return if a given position is inside the physical body.
    /// </summary>
    /// <param name="body">Body to test.</param>
    /// <param name="position">Position to check if inside the body.</param>
    /// <returns>If given point is inside the physical body.</returns>
    public bool TestPointCollision(FarseerPhysics.Dynamics.Body body, Vector2 position)
    {
        // get body transformation
        FarseerPhysics.Common.Transform trans;
        body.GetTransform(out trans);

        // iterate fixtures to see if any of them hit the point
        foreach (var fix in body.FixtureList)
        {
            if (fix.Shape.TestPoint(ref trans, ref position))
                return true;
        }

        // if there are no hits, return false
        return false;
    }

Zauważ, że nie jest to zwykły Box2D, ale Farseer (i w C #), ale powinien mieć dokładnie taki sam interfejs API.

Ronen Ness
źródło