Search Unity

need help checking if any bool in a rotated rectangle is true

Discussion in 'Scripting' started by Dreamerking007, Feb 12, 2020 at 8:12 AM.

  1. Dreamerking007

    Dreamerking007

    Joined:
    Dec 21, 2019
    Posts:
    5
    let's get right down to business i have a 2d bool array and i need to find out if any bool within a rotated rectangle is true. i don't need to know which bool is true just if any are true.

    currently the way i was planning on doing this is to loop through a rectangle that contains the rotated rectangle checking each bool if it is inside(using is left method) and then checking to see if the bool is true. but i was wondering if there is a more efficient way of doing this.
     
  2. csofranz

    csofranz

    Joined:
    Apr 29, 2017
    Posts:
    1,016
    Why don't you show us your approach? Your description is quite vage, and makes very little sense (I assume that you regard the array of bools to be something akin to an Array of Pixels.

    But:
    • is the 'rectangle' the same size (with, height) as the dimensions as the Array?
    • how are bools to be interpreted that are inside a part of the rectangle that lies 'outside' the dimensions of the Array?
    • how to treat parts of the rectangel that - due to rotation and Offset are exactly between two bools in the Array? Interpolate the value? How do you Lerp between true and false?
    Perhaps going straight down to Business was a bit premature. Explain what you want to do, and why, then Show us the code you already have. I'm sure lots of people will be willing to help once we understand that.
     
  3. Dreamerking007

    Dreamerking007

    Joined:
    Dec 21, 2019
    Posts:
    5
    i have yet to actually code this but i was gonna use something similar to this

    float isLeft( Point P0, Point P1, Point P2 )
    {
    return ( (P1.x - P0.x) * (P2.y - P0.y) - (P2.x - P0.x) * (P1.y - P0.y) );
    }
    bool PointInRectangle(Vector2 X, Vector2 Y, Vector2 Z, Vector2 W, Vector2 P)
    {
    return (isLeft(X, Y, P) > 0 && isLeft(Y, Z, P) > 0 && isLeft(Z, W, P) > 0 && isLeft(W, X, p) > 0);
    }


    wasn't quite gonna be this but i haven't actually coded this part because i'm currently working on other code. this is one of the last complex things that i have to do for my game but the way i was thinking of doing this would be rather slow.

    as for your points
    • no the rectangle is a tank that is on the map, the map is constantly changing so i can't use colliders i was gonna use this method to detect collisions, 2d raycasts also won't really work because of a glow effect that i am applying to everything.
    • i was gonna go though a for loop that goes from the highest to lowest x and y on the rotated rectangle and then passing each point in the loop through the code above and then checking if the bool is true.
    • since currently i was just gonna go though a loop it was always gonna come out as an integar number
    so this was roughly gonna be my approach but i don't actually need to find out what bool is true i only wanted to find out if any pixel in the entire rectangle was true so i was wondering if there was a decent way to do this

    edited for clarity

    i was planning to do something similar to how i'm dealing with my bullet collisions but with rectangles instead of circles


    for (int x = 0; x <= circleRadius + circleRadius; x++)
    {
    for (int y = 0; y <= circleRadius + circleRadius; y++)
    {
    if (isSolid[l][sZ + x + ((sW + y) * 324)] == true)
    {
    if (new Vector2(x, y).SqrMagnitude() <= circleRadius * circleRadius)
    {
    DamageTerrain(new Vector2Int(sZ, sW), bulletPool[p, i].explosionRad, l);
    bulletPool[p, i].gameObject.SetActive(false);
    bulletPool[p, i].Active = false;
    return;
    }
    }
    }
    }


    edited to provide example from bullet collisions
     
    Last edited: Feb 12, 2020 at 12:34 PM
  4. csofranz

    csofranz

    Joined:
    Apr 29, 2017
    Posts:
    1,016
    Whoa. That's pretty cryptic code - comments are your friend if you ever want someone else to have a look. Let me see if I correctly interpret this riddling code:

    In isLeft, you have three points and calculate their cross product in order to determine the normal, interpreting the sign as winding: the result being negative or positive (the direction of the normal (z) vector) is interpreted as right or left winding. I hope I'm OK so far.

    You then try to determine if a Point P is inside a rectangle (actually an assumedly convex polygon) defined by the Points x, y, z, w (very, very unfortunate naming here, if you ask me), with the implied assumption by me that they are also given in clockwise orientation.The assumption seems to be that the point is inside the polygon if all triangles you construct with two Points from the polygon and the Point p also return the same winding/normal z value (above Zero)

    The result of the winding test is highly dependent on the order, and I don't know how (what order) you are passing in the rotated rectangle's points. But if XYZW are always in clockwise order this should work.

    How this applies to your game is difficult to see. If your array of bools represens some kind of map (occupied/free tile), and your tank can only occupy integer positions, and you can correctly convert the tank's location to an index into the Array, well, that could work. To optimize (i.e. not iterate over all bools), find the bounding box (that is aligned with the axes) of your tank, and only test those bools inside that bounding box against the rotated.
     
    Last edited: Feb 12, 2020 at 2:47 PM
  5. Dreamerking007

    Dreamerking007

    Joined:
    Dec 21, 2019
    Posts:
    5
    ok yeah i was talking to other people and they say that what i have is roughly the most efficient way so i guess i'll just be doing that
     
  6. Dreamerking007

    Dreamerking007

    Joined:
    Dec 21, 2019
    Posts:
    5
    after much thought one thing that i came up with for this is i could make a jagged for loop i have yet to code it but i'll probably post it by tomorrow

    edit: i came up with something more interesting so this will take me a bit longer
     
    Last edited: Feb 15, 2020 at 9:38 PM
unityunity