Results 1 to 10 of 21

Thread: Circle vs pie segment collision detection

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    it's a record:
    Code:
    TG2Vec2 = record
      strict private
        function GetArr(const Index: Integer): Single; {$IFDEF G2_USE_INLINE} inline; {$ENDIF}
        procedure SetArr(const Index: Integer; const Value: Single); {$IFDEF G2_USE_INLINE} inline; {$ENDIF}
      public
        x, y: Single;
        property Arr[const Index: Integer]: Single read GetArr write SetArr; default;
        class operator Negative(const v: TG2Vec2): TG2Vec2;
        class operator Explicit(const v: TG2Vec2): TG2Vec2Ref;
        class operator Explicit(const v: TG2Vec2Ref): TG2Vec2;
        class operator Explicit(const v: TPoint): TG2Vec2;
        class operator Implicit(const v: TG2Vec2): TG2Vec2Ref;
        class operator Implicit(const v: TG2Vec2Ref): TG2Vec2;
        class operator Implicit(const v: TPoint): TG2Vec2;
        class operator Equal(const v1, v2: TG2Vec2): Boolean;
        class operator NotEqual(const v1, v2: TG2Vec2): Boolean;
        class operator Add(const v1, v2: TG2Vec2): TG2Vec2;
        class operator Add(const v: TG2Vec2; const s: Single): TG2Vec2;
        class operator Subtract(const v1, v2: TG2Vec2): TG2Vec2;
        class operator Subtract(const v: TG2Vec2; const s: Single): TG2Vec2;
        class operator Multiply(const v1, v2: TG2Vec2): Single;
        class operator Multiply(const v: TG2Vec2; const s: Single): TG2Vec2;
        class operator Multiply(const v: TG2Vec2; const m: TG2Mat): TG2Vec2;
        class operator Multiply(const v: TG2Vec2; const m: TG2Mat2): TG2Vec2;
        class operator Divide(const v: TG2Vec2; const s: Single): TG2Vec2;
        procedure SetValue(const _X, _Y: Single); {$IFDEF G2_USE_INLINE} inline; {$ENDIF}
        procedure Normalize; {$IFDEF G2_USE_INLINE} inline; {$ENDIF}
        function Normalized: TG2Vec2; {$IFDEF G2_USE_INLINE} inline; {$ENDIF}
        function Len: Single; {$IFDEF G2_USE_INLINE} inline; {$ENDIF}
        function LenSq: Single; {$IFDEF G2_USE_INLINE} inline; {$ENDIF}
        function Dot(const v: TG2Vec2): Single; {$IFDEF G2_USE_INLINE} inline; {$ENDIF}
        function Cross(const v: TG2Vec2): Single; {$IFDEF G2_USE_INLINE} inline; {$ENDIF}
        function Angle(const v: TG2Vec2): Single; {$IFDEF G2_USE_INLINE} inline; {$ENDIF}
        function Perp: TG2Vec2; {$IFDEF G2_USE_INLINE} inline; {$ENDIF}
        function Reflect(const n: TG2Vec2): TG2Vec2; {$IFDEF G2_USE_INLINE} inline; {$ENDIF}
        function Rotate(const Angle: Single): TG2Vec2; {$IFDEF G2_USE_INLINE} inline; {$ENDIF}
      end;
    if you want I could just attach the whole math unit here.

  2. #2
    Thanks

    That would probably be easier

    cheers,
    Paul

  3. #3
    ok here it is
    Attached Files Attached Files

  4. #4
    Quote Originally Posted by Dan View Post
    ok here it is
    Thanks mate, I will post back and let you know if I got it working

    Thanks again for your time

    EDIT: what about the file "Gen2.inc" that G2Math.pas uses?

    cheers,
    Paul
    Last edited by paul_nicholls; 28-10-2010 at 04:04 AM.

  5. #5
    You can just cut that out, you mostly just want the TG2Vec2 record and the methods that go with it, Gen2.inc controls some of the compiler directives which you don't need.

    EDIT: I took the time and put all the stuff that you may need here
    Code:
      TVec2 = record
      public
        x, y: Single;
        class operator Negative(const v: TVec2): TVec2;
        class operator Add(const v1, v2: TVec2): TVec2;
        class operator Subtract(const v1, v2: TVec2): TVec2;
        class operator Multiply(const v: TVec2; const s: Single): TVec2;
        procedure SetValue(const _X, _Y: Single);
        function Len: Single;
        function Dot(const v: TVec2): Single;
        function Perp: TVec2;
      end;
    
      TCircle = record
      public
        c: TVec2;
        r: Single;
      end;
    
      TPie = record
      public
        c: TVec2;
        r: Single;
        AngStart: Single;
        AngEnd: Single;
      end;
    
    ...
    
    class operator TVec2.Negative(const v: TVec2): TVec2;
    begin
      Result.x := -v.x;
      Result.y := -v.y;
    end;
    
    class operator TVec2.Add(const v1, v2: TVec2): TVec2;
    begin
      Result.x := v1.x + v2.x;
      Result.y := v1.y + v2.y;
    end;
    
    class operator TVec2.Subtract(const v1, v2: TVec2): TVec2;
    begin
      Result.x := v1.x - v2.x;
      Result.y := v1.y - v2.y;
    end;
    
    class operator TVec2.Multiply(const v: TVec2; const s: Single): TVec2;
    begin
      Result.x := v.x * s;
      Result.y := v.y * s;
    end;
    
    procedure TVec2.SetValue(const _X, _Y: Single);
    begin
      x := _X; y := _Y;
    end;
    
    function TVec2.Len: Single;
    begin
      Result := Sqrt(Sqr(x) + Sqr(y));
    end;
    
    function TVec2.Dot(const v: TVec2): Single;
    begin
      Result := x * v.x + y * v.y;
    end;
    
    function TVec2.Perp: TVec2;
    begin
      Result.SetValue(-y, x);
    end;
    
    procedure SinCos(const Angle: Single; var s, c: Single);
    asm
      fld Angle
      fsincos
      fstp [edx]
      fstp [eax]
      fwait
    end;
    
    function CircleVsPieIntersect(const c: TCircle; const p: TPie): Boolean;
      var v1, v2, n1, n2, n3, a1, a2: TVec2;
      var d1, d2, l: Single;
    begin
      l := (c.c - p.c).Len;
      if l > c.r + p.r then
      begin
        Result := False;
        Exit;
      end;
      SinCos(p.AngStart, v1.y, v1.x);
      SinCos(p.AngEnd, v2.y, v2.x);
      n3 := -(v1 + v2);
      if (n3.Dot(c.c) > n3.Dot(p.c))
      and (l > c.r) then
      begin
        Result := False;
        Exit;
      end;
      n1 := v1.Perp; if n1.Dot(v1 - v2) < 0 then n1 := -n1;
      n2 := v2.Perp; if n2.Dot(v2 - v1) < 0 then n2 := -n2;
      d1 := n1.Dot(p.c) + c.r;
      d2 := n2.Dot(p.c) + c.r;
      if (n1.Dot(c.c) > d1)
      or (n2.Dot(c.c) > d2) then
      begin
        Result := False;
        Exit;
      end;
      a1 := p.c + v1 * p.r;
      a2 := p.c + v2 * p.r;
      if (
        (n1.Dot(c.c) > n1.Dot(p.c))
        and (v1.Dot(c.c) > v1.Dot(a1))
        and ((c.c - a1).Len > c.r)
      )
      or (
        (n2.Dot(c.c) > n2.Dot(p.c))
        and (v2.Dot(c.c) > v2.Dot(a2))
        and ((c.c - a2).Len > c.r)
      ) then
      begin
        Result := False;
        Exit;
      end;
      Result := True;
    end;
    Last edited by Dan; 28-10-2010 at 05:16 AM.

  6. #6
    Quote Originally Posted by Dan View Post
    You can just cut that out, you mostly just want the TG2Vec2 record and the methods that go with it, Gen2.inc controls some of the compiler directives which you don't need.
    Ah ok, no worries

    cheers,
    Paul

  7. #7
    hmm...the code seems to be returning true for me most of the time, so I get flickering energy discharges at the target as it thinks the circle and pie are intersecting lots...

    I am setting up the circle and pie like this:

    Code:
        BeamHasHitPlayer := False;
    
        if Assigned(FPlayer) then
        begin
          Circle.c := G2Vec2(FPlayer.x,FPlayer.y);
          Circle.r := FPlayer.Width * 0.4;
    
          Pie.c := G2Vec2(aSentry.x,aSentry.y);
          Pie.r := aSentry.BeamRange;
          Pie.AngStart := aSentry.Angle - aSentry.BeamWidth/2;
          Pie.AngEnd   := aSentry.Angle + aSentry.BeamWidth/2;
    
          BeamHasHitPlayer := CircleVsPieIntersect(Circle,Pie);
        end;
    Any ideas?

    If it helps, the beam width is 50 degrees wide, and the screen coordinate system being used is this (if it makes a difference?):

    Code:
    0,0
    +----------------------  +X
    |
    |
    |
    |
    |
    |
    |
    
    +Y
    cheers,
    Paul

  8. #8
    Quote Originally Posted by paul_nicholls View Post
    @?ëu?±o Mart??nez and User137: thanks guys, but you seem to have overlooked the fact that I want to check if a circle, not a point is between the 2 angle
    Details... BTW that was teh first idea I had, and I'm sure it made you think, don't you?
    No signature provided yet.

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •