I am making a simple game in which i have a ball and an arc revolving around the center. When user touches the screen the ball moves in the direction of pointer and hits the arc
arc (float x, float y, float radius, float start, float degrees
It seems that x,y
is circle center, start
is starting angle, degrees
is sweep angle, so end angle is end = start + degrees
If your intersection point is ix, iy
, then you can check signs of these cross products:
cp_1 = (ix-x)*sin(start)-(iy-y)*Cos(start)
cp_2 = (ix-x)*sin(end)-(iy-y)*Cos(end)
If cp1 has negative sign and cp2 is positive (for positive arc direction Degrees), then (ix,iy)
intersection point is between (start,end)
arc ends. (works for Abs(degrees) < Pi=180
)
Delphi example generate arc from -15 to +30 degrees, and check whether rays from cx,cy
to some points intersect this arc:
function IsPointInArcLimits(cx, cy, ix, iy, StartAngle, Deg: Double): Boolean;
var
EndAngle, cp_1, cp_2: Double;
begin
EndAngle := DegToRad(StartAngle + Deg);
StartAngle := degToRad(StartAngle);
cp_1 := (ix - cx) * Sin(StartAngle) - (iy - cy) * Cos(StartAngle);
cp_2 := (ix - cx) * Sin(EndAngle) - (iy - cy) * Cos(EndAngle);
Result := (cp_1 <= 0) and (cp_2 >= 0);
end;
var
cx, cy, ix, iy, StartAngle, Degrees: Integer;
begin
cx := 0;
cy := 0;
ix := 10;
StartAngle := -15;
Degrees := 45;
for iy := -5 to 7 do
if IsPointInArcLimits(cx, cy, ix, iy, StartAngle, Degrees) then
Memo1.Lines.Add(Format('Yes y=%d an=%f arc %d+%d',
[iy, RadToDeg(ArcTan(iy / ix)), StartAngle, Degrees]))
else
Memo1.Lines.Add(Format('No y=%d an=%f arc %d+%d',
[iy, RadToDeg(ArcTan(iy / ix)), StartAngle, Degrees]));
output:
No y=-5 an=-26.57 arc -15+45
No y=-4 an=-21.80 arc -15+45
No y=-3 an=-16.70 arc -15+45
Yes y=-2 an=-11.31 arc -15+45
Yes y=-1 an=-5.71 arc -15+45
Yes y=0 an=0.00 arc -15+45
Yes y=1 an=5.71 arc -15+45
Yes y=2 an=11.31 arc -15+45
Yes y=3 an=16.70 arc -15+45
Yes y=4 an=21.80 arc -15+45
Yes y=5 an=26.57 arc -15+45
No y=6 an=30.96 arc -15+45
No y=7 an=34.99 arc -15+45