How to calculate if point is inside an oval.

BlitzMax Forums/BlitzMax Beginners Area/How to calculate if point is inside an oval.

Sokurah(Posted 2010) [#1]
I'm sorry for asking about this simple thing - I'm sure it's been answered before ...but I just can't find a simple solution that doesn't look overly complex.

Here's a small example that draws an oval.
I need to be able to tell if a point is inside an oval like this.

Can anyone help?

Graphics 1024, 768, 0
HideMouse

Repeat
	Cls
	'Draw oval
	For a = 0 To 360
		x = 430 * Sin(a) + 512
		y = 320 * -Cos(a) + 384
		Plot x, y
	Next
	
	Plot MouseX(), MouseY()
	
	Flip
Until KeyHit(KEY_ESCAPE)



Warpy(Posted 2010) [#2]
If the oval is at position (ox,oy) and has width 2w and height 2h, then:

Function inoval(x#,y#,ox#,oy#,w#,h#)
  dx# = (x-ox)/w
  dy# = (y-oy)/h
  If dx*dx+dy*dy<1
    Return True
  Else
    Return False
  Endif
End Function


This is because an oval is just a stretched circle - if you start with a circle of radius 1 and scale it horizontally by a factor of w and vertically by a factor of h, you get an oval of width 2w and height 2h.
So if you do the opposite transformations, you can find out if a point is in your oval by checking if some other point is inside a circle of radius 1.
Subtract the oval's position from your point's position, to get the relative co-ordinates.
Divide the relative co-ordinates by the oval's width and height to get the scaled co-ordinates.
Now if the scaled co-ordinates are inside the circle of radius 1, that is if the distance to the origin is less than 1, then the original point was inside the oval.


Midimaster(Posted 2010) [#3]
Graphics 1000,800

centerX#= 512
centery#= 384
Width#= 430
Height#=120

factor#=width/height



Repeat
	testX#=MouseX()
	testY#=MouseY()

	distX# = testX-centerX
	distY# = testY-centerY

	direction# = ATan2(distX/factor,distY)
	direction=(direction +360) Mod 360
	ovalX# = Sin(direction) * Width
	ovalY# = Cos(direction) * Height
	
	
	DistTest#=Sqr(distX^2+distY^2)
	DistReal=Sqr(ovalX^2+OvalY^2)
	
	Cls
	SetColor 222,222,222
	DrawText DistTest-DistReal,100,100 
	For i=0 To 360
		Plot centerX+ Sin(i)*Width,centerY+Cos(i)*Height
	Next
	DrawOval centerX,centerY,8,8
	
	If DistTest>DistReal Then
		SetColor 255,0,0
	Else
		SetColor 0,255,0	
	EndIf
	DrawOval testX,testY,8,8
	
	SetColor 0,0,255
	DrawOval ovalX+CenterX,ovalY + CenterY, 8, 8

	Flip 0
	Delay 100
	
		
Until KeyHit(key_escape)


This code can handle any mouse coordinates. At first it calculates the angle which the Mouse has in relation to the oval center. Then it calculates where a point on the oval would be, if it has the same angle. Then you can calcultate the distances of both Mouse and Ovalpoint to the center.


So you can reduce this sample to a function:

Function IsInside%(testx#, testy#, CenterX# ,CenterY#, Width#, Height#)

	Local Direction#, distX#, distY#, ovalX#, ovalY#, DistTest#, DistReal#, factor#

	distX = testX-centerX
	distY = testY-centerY
	factor= Width/Height


	direction = ATan2(distX/factor,distY)
	direction=(direction +360) Mod 360

	ovalX# = Sin(direction) * Width
	ovalY# = Cos(direction) * Height

	DistTest=Sqr(distX^2+distY^2)
	DistReal=Sqr(ovalX^2+OvalY^2)

	If DistTest<DistReal Then
		Return True
	EndIf

End Function



Sokurah(Posted 2010) [#4]
Thanks guys. That's perfect.

I've used Warpys code but I've saved both in case I need it later.

You Roolz. :)


ImaginaryHuman(Posted 2010) [#5]
I like warpy solution, I was going to suggest something similar but not as clever.