Skip to content

Instantly share code, notes, and snippets.

@SteffenBlake
Created June 22, 2024 19:57
Show Gist options
  • Save SteffenBlake/3b9f4942d98a75da8924297b18b55bb6 to your computer and use it in GitHub Desktop.
Save SteffenBlake/3b9f4942d98a75da8924297b18b55bb6 to your computer and use it in GitHub Desktop.

To determine if two moving rectangles will collide and to find the start, middle, and end points of their impact times, we need to consider the paths of the rectangles and detect any intersections along their trajectories. Here's how to approach the problem step-by-step:

Step-by-Step Algorithm

  1. Define the Rectangles and Their Movements:

    • For each rectangle, you have its initial position, dimensions, and movement vector.
  2. Parametrize the Motion:

    • Represent the position of each rectangle as a function of time.

    • For Rectangle R1:

      [

      R1(t) = \left( x_{1}(t), y_{1}(t), w_{1}, h_{1} \right)

      ]

      where ( x_{1}(t) = x_{1} + V_{1x} \cdot t ) and ( y_{1}(t) = y_{1} + V_{1y} \cdot t )

    • For Rectangle R2:

      [

      R2(t) = \left( x_{2}(t), y_{2}(t), w_{2}, h_{2} \right)

      ]

      where ( x_{2}(t) = x_{2} + V_{2x} \cdot t ) and ( y_{2}(t) = y_{2} + V_{2y} \cdot t )

  3. Check for Overlap Over Time:

    • For collision, the rectangles must overlap at some time ( t ) within the frame interval ( [0, 1] ).

    • To check overlap, the following conditions must be satisfied simultaneously:

      [

      x_{1}(t) + w_{1} > x_{2}(t) \quad \text{and} \quad x_{1}(t) < x_{2}(t) + w_{2}

      ]

      [

      y_{1}(t) + h_{1} > y_{2}(t) \quad \text{and} \quad y_{1}(t) < y_{2}(t) + h_{2}

      ]

  4. Solve for Time Intervals:

    • These inequalities define the time intervals during which the rectangles overlap.

    • Solve for ( t ) where these conditions hold:

      [

      t_{x1} = \frac{x_{2} - (x_{1} + w_{1})}{V_{1x} - V_{2x}}

      ]

      [

      t_{x2} = \frac{(x_{2} + w_{2}) - x_{1}}{V_{1x} - V_{2x}}

      ]

      [

      t_{y1} = \frac{y_{2} - (y_{1} + h_{1})}{V_{1y} - V_{2y}}

      ]

      [

      t_{y2} = \frac{(y_{2} + h_{2}) - y_{1}}{V_{1y} - V_{2y}}

      ]

    • Determine the intersection intervals of these ( t )-values, considering ( t \in [0, 1] ).

  5. Find Impact Times:

    • The start of impact ( t_{\text{start}} ) is the maximum of the starting overlap times.

    • The end of impact ( t_{\text{end}} ) is the minimum of the ending overlap times.

    • The middle time ( t_{\text{middle}} ) is the average of ( t_{\text{start}} ) and ( t_{\text{end}} ).

  6. Calculate Positions at Impact Times:

    • Compute the positions of the rectangles at ( t_{\text{start}} ), ( t_{\text{middle}} ), and ( t_{\text{end}} ).

Example Calculation

Let's assume the rectangles have the following properties:

  • ( R1 ): initial position ((x1, y1)), dimensions ((w1, h1)), vector ( V1 = (V1x, V1y) )

  • ( R2 ): initial position ((x2, y2)), dimensions ((w2, h2)), vector ( V2 = (V2x, V2y) )

Here's a Python-like pseudocode to calculate the collision times and positions:

def will_collide(x1, y1, w1, h1, V1x, V1y, x2, y2, w2, h2, V2x, V2y):

    # Solve for t intervals

    t_x1 = (x2 - (x1 + w1)) / (V1x - V2x)

    t_x2 = ((x2 + w2) - x1) / (V1x - V2x)

    t_y1 = (y2 - (y1 + h1)) / (V1y - V2y)

    t_y2 = ((y2 + h2) - y1) / (V1y - V2y)

    

    t_start = max(0, min(t_x1, t_x2), min(t_y1, t_y2))

    t_end = min(1, max(t_x1, t_x2), max(t_y1, t_y2))

    

    if t_start <= t_end:

        t_middle = (t_start + t_end) / 2

        

        # Calculate positions at impact times

        R1_start = (x1 + V1x * t_start, y1 + V1y * t_start)

        R2_start = (x2 + V2x * t_start, y2 + V2y * t_start)

        

        R1_middle = (x1 + V1x * t_middle, y1 + V1y * t_middle)

        R2_middle = (x2 + V2x * t_middle, y2 + V2y * t_middle)

        

        R1_end = (x1 + V1x * t_end, y1 + V1y * t_end)

        R2_end = (x2 + V2x * t_end, y2 + V2y * t_end)

        

        return {

            'start': (t_start, R1_start, R2_start),

            'middle': (t_middle, R1_middle, R2_middle),

            'end': (t_end, R1_end, R2_end)

        }

    else:

        return None  # No collision

# Example usage

result = will_collide(x1, y1, w1, h1, V1x, V1y, x2, y2, w2, h2, V2x, V2y)

if result:

    print("Collision times and positions:", result)

else:

    print("No collision detected.")

This algorithm first calculates the potential times of collision based on the relative positions and velocities of the rectangles, then verifies if those times fall within the frame interval. Finally, it calculates the positions of the rectangles at the start, middle, and end of the collision period.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment