Another Convex / Concave test

Monkey Forums/Monkey Code/Another Convex / Concave test

NoOdle(Posted 2011) [#1]
Wrote this is Blitzmax many moons ago, quickly converted to monkey.


Import mojo


Const CONCAVE : Int = -1
Const CONVEX : Int = 1


Global MaxPoints : Int = -1
Global Points : XY[ 10 ]


Class XY
	Field x : Int
	Field y : Int
End Class



Class MyApp Extends App


	
	Method OnCreate()


		SetUpdateRate 60

		AddPoint( Points, 100, 300 )
		AddPoint( Points, 200, 100 )
		AddPoint( Points, 300, 300 )
		'change the line below to 200, 200 to see a concave shape
		AddPoint( Points, 200, 400 )
		AddPoint( Points, 100, 300 )

	End Method
	
	



	Method OnUpdate()


	End Method
	



	Method OnRender()
		Cls 0, 0, 0
		
		DrawPoints( Points )
	
		Local Result:Int = ConvexTest(Points,MaxPoints)

		If Result = CONVEX
			DrawText("Shape is Convex!",0,0)
		Elseif Result = CONCAVE
			DrawText("Shape is Concave!",0,0)	
		Else
			DrawText("Unkown!",0,0)
		Endif
		

	End Method
	

End Class



Function Main()
	New MyApp()
End Function




Function AddPoint( p:XY[], x:Int, y:Int )
	MaxPoints = MaxPoints + 1
	p[MaxPoints] = New XY()
	p[MaxPoints].x = x
	p[MaxPoints].y = y
End Function





Function DrawPoints( p : XY[] )
	Local n : Int
	Local x1 : Float
	Local y1 : Float
	Local x2 : Float
	Local y2 : Float
	For n = 0 To MaxPoints - 1
		x1 = p[ n ].x
		y1 = p[ n ].y
		x2 = p[ n + 1 ].x
		y2 = p[ n + 1 ].y
		DrawLine( x1, y1, x2, y2 )
	Next
End Function





Function ConvexTest:Int(p:XY[],n:Int)
	Local i:Int
	Local j:Int
	Local k:Int
	Local flag:Int = 0
	Local z:Float
	If (n < 3) Return 0
	For i=0 Until n
		j = (i + 1) Mod n
		k = (i + 2) Mod n
		z = (p[j].x - p[i].x) * (p[k].y - p[j].y)
		z = z - (p[j].y - p[i].y) * (p[k].x - p[j].x)
		If (z < 0)
			flag = flag | 1
		Else 
			If (z > 0) flag = flag | 2
		Endif
		If (flag = 3) Return(CONCAVE)
	Next
	If (flag <> 0) Return(CONVEX) Else Return 0
End Function




NoOdle(Posted 2011) [#2]
here are polygon area and centre of mass functions... haven't fully tested but it appears to work

Function PolygonArea : Float( p : XY[], n : Int )
	Local i : Int
	Local j : Int
	Local area : Float
	For i = 0 To n - 1
		j = (i + 1) Mod n
		area = area + p[ i ].x * p[ j ].y
		area = area - p[ i ].y * p[ j ].x
	Next
	area = area / 2
	Return area
End Function





Function PolygonCenterOfMass : XY( p : XY[], n : Int )
	Local A : Float = PolygonArea( p , n )
	Local res : XY = New XY()
	Local i : Int
	Local j : Int
	Local factor : Float = 0
	For i = 0 To n - 1
		j = (i + 1) Mod n
		factor = (p[ i ].x * p[ j ].y - p[ j ].x * p[ i ].y)
		res.x = res.x + (p[ i ].x + p[ j ].x) * factor
		res.y = res.y + (p[ i ].y + p[ j ].y) * factor
	Next
	A = A * 6.0
	factor = 1 / A
	res.x = res.x * factor
	res.y = res.y * factor
	Return res
End Function