About Monkey 2 › Forums › Monkey 2 Code Library › Oddball's polygon collision code conversion.
This topic contains 3 replies, has 4 voices, and was last updated by
Amon
1 year, 2 months ago.
Viewing 4 posts - 1 through 4 (of 4 total)
-
AuthorPosts
-
January 17, 2018 at 5:14 am #12899
I thought these might be useful to somebody. here is the Blitzmax polygon code by Oddball from here:
http://www.mojolabs.nz/codearcs.php?code=1676
converted to monkey2:[/crayon]Monkey123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468[crayon-5cba154114781627551030 inline="true" ]Namespace myapp#Import "<std>"#Import "<mojo>"Using std..Using mojo..Class MyWindow Extends WindowField verts:Float[]=New Float[](-25.0,0.0,-75.0,75.0,0.0,50.0,100.0,100.0,50.0,25.0,100.0,0.0,50.0,-25.0,100.0,-100.0,0.0,-50.0,-75.0,-75.0)Field cursor:Float[]=New Float[](0.0,-50.0,100.0,-100.0,50.0,0.0,100.0,100.0,0.0,50.0,-100.0,100.0,-50.0,0.0,-100.0,-100.0)Field ang:Float =0Field coltype:Int =0Field rad:Float =20Method New( title:String="Simple mojo app",width:Int=800,height:Int=600,flags:WindowFlags=Null )Super.New( title,width,height,flags )EndMethod OnRender( canvas:Canvas ) OverrideApp.RequestRender()If Keyboard.KeyHit(Key.Key1) Then coltype=0If Keyboard.KeyHit(Key.Key2) Then coltype=1If Keyboard.KeyHit(Key.Key3) Then coltype=3If Keyboard.KeyHit(Key.Key4) Then coltype=2Local x:Float=400Local y:Float=300Local rot:Float=(ang)Local sx:Float=Cos((ang))/2+1.5Local sy:Float=Sin((ang))/2+1.5Local ox:Float=Cos((ang/2))*50Local oy:Float=Sin((ang/2))*50Local lx:Float=400+Cos((-ang))*300Local ly:Float=300+Sin((-ang))*300Local mx:Int=Mouse.XLocal my:Int=Mouse.YSelect coltypeCase 0If PointInTFormPoly(mx,my,verts,x,y,rot,sx,sy)canvas.Color = New Color(0,1,0)Elsecanvas.Color = New Color(0,.5,.5)EndIfCase 1If CircleToTFormPoly(mx,my,rad,verts,x,y,rot,sx,sy)canvas.Color = New Color(0,1,1)Elsecanvas.Color = New Color(0,.5,.5)EndIfCase 2If TFormPolyToTFormPoly(verts,x,y,rot,sx,sy,cursor,mx,my,-rot,0.5,0.5)canvas.Color = New Color(0,1,1)Elsecanvas.Color = New Color(0,.5,.5)EndIfCase 3If LineToTFormPoly(mx,my,lx,ly,verts,x,y,rot,sx,sy)canvas.Color = New Color(0,1,1)Elsecanvas.Color = New Color(0,.5,.5)EndIfEnd SelectDrawPoly(canvas,verts,True,x,y,rot,sx,sy)'canvas.PushMatrix()canvas.Color= New Color(1,1,1)canvas.DrawText("Select 1, 2, 3 or 4",5,0)canvas.DrawText("1: PointToTFormPoly",5,20)canvas.DrawText("2: CircleToTFormPoly",5,35)canvas.DrawText("3: LineToTFormPoly",5,50)canvas.DrawText("4: TFormPolyToTFormPoly",5,65)canvas.Color = New Color(1,0,0)Select coltypeCase 0canvas.DrawLine(mx,my-10,mx,my+10)canvas.DrawLine(mx-10,my,mx+10,my)Case 1canvas.DrawOval(mx-rad,my-rad,rad*2,rad*2)Case 2DrawPoly(canvas,cursor,True,mx,my,-rot,0.5,0.5)Case 3canvas.DrawLine(mx,my,lx,ly)End Select'canvas.PopMatrix()ang+=Pi/180.0'ang = Pi/180.0 * 90EndEndFunction Main()New AppInstanceNew MyWindowApp.Run()EndFunction TFormPolyToTFormPoly:Bool( p1_xy:Float[], p1_x:Float=0, p1_y:Float=0,p1_rot:Float=0, p1_scale_x:Float=1, p1_scale_y:Float=1,p2_xy:Float[], p2_x:Float=0, p2_y:Float=0,p2_rot:Float=0, p2_scale_x:Float=1, p2_scale_y:Float=1)If p1_xy.Length<6 Or (p1_xy.Length&1) Return FalseIf p2_xy.Length<6 Or (p2_xy.Length&1) Return FalseLocal tform1_xy:Float[]=TFormPoly(p1_xy,p1_x,p1_y,p1_rot,p1_scale_x,p1_scale_y)Local tform2_xy:Float[]=TFormPoly(p2_xy,p2_x,p2_y,p2_rot,p2_scale_x,p2_scale_y)If PolyToPoly(tform1_xy,tform2_xy)Return TrueElseReturn FalseEndIfEnd FunctionFunction PolyToTFormPoly:Bool( p1_xy:Float[], p2_xy:Float[],p2_x:Float=0, p2_y:Float=0, rot:Float=0,scale_x:Float=1, scale_y:Float=1)If p1_xy.Length<6 Or (p1_xy.Length&1) Return FalseIf p2_xy.Length<6 Or (p2_xy.Length&1) Return FalseLocal tform_xy:Float[]=TFormPoly(p2_xy,p2_x,p2_y,rot,scale_x,scale_y)If PolyToPoly(p1_xy,tform_xy)Return TrueElseReturn FalseEndIfEnd FunctionFunction PolyToPoly:Bool( p1_xy:Float[], p2_xy:Float[] )If p1_xy.Length<6 Or (p1_xy.Length&1) Return FalseIf p2_xy.Length<6 Or (p2_xy.Length&1) Return FalseFor Local i:Int=0 Until p1_xy.Length Step 2If PointInPoly(p1_xy[i],p1_xy[i+1],p2_xy) Then Return TrueNextFor Local i:Int=0 Until p2_xy.Length Step 2If PointInPoly(p2_xy[i],p2_xy[i+1],p1_xy) Then Return TrueNextLocal l1_x1:Float=p1_xy[p1_xy.Length-2]Local l1_y1:Float=p1_xy[p1_xy.Length-1]For Local i1:Int=0 Until p1_xy.Length Step 2Local l1_x2:Int =p1_xy[i1]Local l1_y2:Int=p1_xy[i1+1]Local l2_x1:Float=p2_xy[p2_xy.Length-2]Local l2_y1:Float=p2_xy[p2_xy.Length-1]For Local i2:Int=0 Until p2_xy.Length Step 2Local l2_x2:Int=p2_xy[i2]Local l2_y2:Int=p2_xy[i2+1]If LinesCross(l1_x1,l1_y1,l1_x2,l1_y2,l2_x1,l2_y1,l2_x2,l2_y2)Return TrueEndIfl2_x1=l2_x2l2_y1=l2_y2Nextl1_x1=l1_x2l1_y1=l1_y2NextReturn FalseEnd FunctionFunction CircleToTFormPoly:Bool( circle_x:Float, circle_y:Float, radius:Float,xy:Float[], poly_x:Float=0, poly_y:Float=0, rot:Float=0,scale_x:Float=1, scale_y:Float=1)If xy.Length<6 Or (xy.Length&1) Return FalseLocal tform_xy:Float[]=TFormPoly(xy,poly_x,poly_y,rot,scale_x,scale_y)Return CircleToPoly(circle_x,circle_y,radius,tform_xy)End FunctionFunction CircleToPoly:Bool( circle_x:Float, circle_y:Float, radius:Float, xy:Float[] )If xy.Length<6 Or (xy.Length&1) Return FalseIf PointInPoly(circle_x,circle_y,xy) Then Return TrueLocal x1:Float=xy[xy.Length-2]Local y1:Float=xy[xy.Length-1]For Local i:Int=0 Until xy.Length Step 2Local x2:Float=xy[i]Local y2:Float=xy[i+1]If LineToCircle(x1,y1,x2,y2,circle_x,circle_y,radius) Then Return Truex1=x2y1=y2NextReturn FalseEnd FunctionFunction LineToTFormPoly:Bool( line_x1:Float, line_y1:Float, line_x2:Float, line_y2:Float,xy:Float[], poly_x:Float=0, poly_y:Float=0,rot:Float=0, scale_x:Float=1, scale_y:Float=1)If xy.Length<6 Or (xy.Length&1) Return FalseTFormGlobalToLocal(Varptr line_x1,Varptr line_y1,poly_x,poly_y,rot,scale_x,scale_y)TFormGlobalToLocal(Varptr line_x2,Varptr line_y2,poly_x,poly_y,rot,scale_x,scale_y)Return LineToPoly(line_x1,line_y1,line_x2,line_y2,xy)End FunctionFunction LineToPoly:Bool( line_x1:Float, line_y1:Float, line_x2:Float, line_y2:Float, xy:Float[] )If xy.Length<6 Or (xy.Length&1) Return FalseIf PointInPoly(line_x1,line_y1,xy) Then Return TrueLocal poly_x1:Float=xy[xy.Length-2]Local poly_y1:Float=xy[xy.Length-1]For Local i:Int=0 Until xy.Length Step 2Local poly_x2:Float=xy[i]Local poly_y2:Float=xy[i+1]If LinesCross(line_x1,line_y1,line_x2,line_y2,poly_x1,poly_y1,poly_x2,poly_y2) Then Return Truepoly_x1=poly_x2poly_y1=poly_y2NextReturn FalseEnd FunctionFunction PointInTFormPoly:Bool( point_x:Float, point_y:Float, xy:Float[],poly_x:Float=0, poly_y:Float=0, rot:Float=0,scale_x:Float=1, scale_y:Float=1)If xy.Length<6 Or (xy.Length&1) Return FalseTFormGlobalToLocal(Varptr point_x, Varptr point_y,poly_x,poly_y,rot,scale_x,scale_y)Return PointInPoly(point_x,point_y,xy)End FunctionFunction PointInPoly:Bool( point_x:Float, point_y:Float, xy:Float[] )If xy.Length<6 Or (xy.Length&1) Return FalseLocal x1:Float=xy[xy.Length-2]Local y1:Float=xy[xy.Length-1]Local cur_quad:Int=GetQuad(point_x,point_y,x1,y1)Local next_quad:IntLocal total:IntFor Local i:Int=0 Until xy.Length Step 2Local x2:Float=xy[i]Local y2:Float=xy[i+1]next_quad=GetQuad(point_x,point_y,x2,y2)Local diff:Int=next_quad-cur_quadSelect diffCase 2,-2If ( x2 - ( ((y2 - point_y) * (x1 - x2)) / (y1 - y2) ) )<point_xdiff=-diffEndIfCase 3diff=-1Case -3diff=1End Selecttotal+=diffcur_quad=next_quadx1=x2y1=y2NextIf Abs(total)=4 Then Return True Else Return FalseEnd FunctionFunction TFormPoly:Float[]( xy:Float[], tform_x:Float=0, tform_y:Float=0, rot:Float=0,scale_x:Float=1, scale_y:Float=1)If xy.Length<6 Or (xy.Length&1) Return NullLocal tform_xy:Float[]=xy.Slice(0,xy.Length)For Local i:Int=0 Until tform_xy.Length Step 2TFormLocalToGlobal(Varptr tform_xy[i],Varptr tform_xy[i+1],tform_x,tform_y,rot,scale_x,scale_y)NextReturn tform_xyEnd FunctionFunction TFormGlobalToLocal( point_x:Float Ptr, point_y:Float Ptr, '8888888888888888888888tform_x:Float=0, tform_y:Float=0, rot:Float=0,scale_x:Float=1, scale_y:Float=1)point_x[0]-=tform_xpoint_y[0]-=tform_y'Print point_x[0]+" "+point_y[0]Local mag:Float=Sqrt(point_x[0]*point_x[0]+point_y[0]*point_y[0])Local ang:Float=ATan2(point_y[0],point_x[0])point_x[0]=Cos((ang-rot))*magpoint_y[0]=Sin((ang-rot))*magpoint_x[0]/=scale_xpoint_y[0]/=scale_y'Print point_x[0]+" "+point_y[0]End FunctionFunction TFormLocalToGlobal( point_x:Float Ptr, point_y:Float Ptr,tform_x:Float=0, tform_y:Float=0, rot:Float=0,scale_x:Float=1, scale_y:Float=1)point_x[0]*=scale_xpoint_y[0]*=scale_yLocal mag:Float=Sqrt(point_x[0]*point_x[0]+point_y[0]*point_y[0])Local ang:Float=ATan2(point_y[0],point_x[0])point_x[0]=Cos((ang+rot))*magpoint_y[0]=Sin((ang+rot))*magpoint_x[0]+=tform_xpoint_y[0]+=tform_yEnd Function'Adapted from Fredborg's codeFunction LinesCross:Bool( x0:Float, y0:Float , x1:Float, y1:Float,x2:Float ,y2:Float, x3:Float, y3:Float )Local n:Float=(y0-y2)*(x3-x2)-(x0-x2)*(y3-y2)Local d:Float=(x1-x0)*(y3-y2)-(y1-y0)*(x3-x2)If Abs(d) < 0.0001' Lines are parallel!Return FalseElse' Lines might cross!Local Sn:Float=(y0-y2)*(x1-x0)-(x0-x2)*(y1-y0)Local AB:Float=n/dIf AB>0.0 And AB<1.0Local CD:Float=Sn/dIf CD>0.0 And CD<1.0' Intersection PointLocal X:Int=x0+AB*(x1-x0)Local Y:Int=y0+AB*(y1-y0)Return TrueEnd IfEnd If' Lines didn't cross, because the intersection was beyond the end points of the linesEndIf' Lines do Not cross!Return FalseEnd Function'Adapted from TomToad's codeFunction LineToCircle:Bool( x1:Float, y1:Float, x2:Float, y2:Float, px:Float, py:Float, r:Float )Local sx:Float = x2-x1Local sy:Float = y2-y1Local q:Float = ((px-x1) * (x2-x1) + (py - y1) * (y2-y1)) / (sx*sx + sy*sy)If q < 0.0 Then q = 0.0If q > 1.0 Then q = 1.0Local cx:Float=(1-q)*x1+q*x2Local cy:Float=(1-q)*y1 + q*y2If PointToPointDist(px,py,cx,cy) < rReturn TrueElseReturn FalseEndifEnd FunctionFunction PointToPointDist:Float( x1:Float, y1:Float, x2:Float, y2:Float )Local dx:Float = x1-x2Local dy:Float = y1-y2Return Sqrt(dx*dx + dy*dy)End FunctionFunction GetQuad:Int(axis_x:Float,axis_y:Float,vert_x:Float,vert_y:Float)If vert_x<axis_xIf vert_y<axis_yReturn 1ElseReturn 4EndIfElseIf vert_y<axis_yReturn 2ElseReturn 3EndIfEndIfEnd FunctionFunction DrawPoly(canvas:Canvas,xy:Float[], fill:Int=True, x:Float=0, y:Float=0,rot:Float=0,sx:Float=1,sy:Float=1 )canvas.PushMatrix()canvas.Translate(x,y)canvas.Rotate(-rot)canvas.Scale(sx,sy)If fillcanvas.DrawPoly(xy)ElseLocal x1:Float=xy[xy.Length-2]Local y1:Float=xy[xy.Length-1]For Local i:Int=0 Until xy.Length Step 2Local x2:Float=xy[i]Local y2:Float=xy[i+1]canvas.DrawLine(x1,y1,x2,y2) ',x-0.5,y-0.5)x1=x2y1=y2NextEndIfcanvas.PopMatrix()End FunctionJanuary 17, 2018 at 9:00 am #12901Cool!
Also I have been looking for the Blitz archives this week, since wasted.nz is down this site will come handy.
January 17, 2018 at 9:16 pm #12904@cocon That is the new home of skidracer’s Blitz/Monkey1 web archive, it just moved from wasted.nz.
Thanks, Jesse!
January 21, 2018 at 11:53 pm #13159Thank you, Jesse. This is cool.
-
AuthorPosts
Viewing 4 posts - 1 through 4 (of 4 total)
You must be logged in to reply to this topic.