Hello folks,
I always wanted to push some of my snippets to the board, but I was always to buisy to update them or to comment them...
... anyway I think it is still a good idea to share as much as we can, maybe someone will need this.
This one is a little snippet that will create a virtual polygon and check it for convex / concave.
That code can be useful for several things although it has to be extended. I will try to get some point in volume
commands running too!
Cheers!
Version 1:
// Project: Convex or Concave
// Created: 2015-10-08
// Alex Schmidt 2015 - online-arts.de
// Convex or Concave
// set window properties
SetWindowTitle( "Convex or Concave" )
SetWindowSize( 1280, 720, 0 )
// set display properties
SetVirtualResolution( 1280, 720 )
SetOrientationAllowed( 1, 1, 1, 1 )
// define a point
type point_def
x# as float
y# as float
txt as integer
rad# as float
endtype
// define a poly with 4 points
type poly_def
p_a as point_def
p_b as point_def
p_c as point_def
p_d as point_def
convex as integer
endtype
dim polygon[0] as poly_def
// define first polygon
polygon[0].p_a.x#=600.0
polygon[0].p_a.y#=50.0
polygon[0].p_b.x#=200.0
polygon[0].p_b.y#=80.0
polygon[0].p_c.x#=80.0
polygon[0].p_c.y#=400.0
polygon[0].p_d.x#=400.0
polygon[0].p_d.y#=400.0
do
// user output
if polygon[0].convex=0 then print("concave")
if polygon[0].convex=1 then print("convex")
draw_polygon(0)
handle_polygon(0)
Sync()
loop
// being able to modify is acually pretty great
function handle_polygon(num)
if GetPointerState()=1
if GetDistance#( GetPointerX(), GetPointerY(), polygon[0].p_a.x#, polygon[0].p_a.y#)<20.0
polygon[0].p_a.x#=GetPointerX()
polygon[0].p_a.y#=GetPointerY()
endif
if GetDistance#( GetPointerX(), GetPointerY(), polygon[0].p_b.x#, polygon[0].p_b.y#)<20.0
polygon[0].p_b.x#=GetPointerX()
polygon[0].p_b.y#=GetPointerY()
endif
if GetDistance#( GetPointerX(), GetPointerY(), polygon[0].p_c.x#, polygon[0].p_c.y#)<20.0
polygon[0].p_c.x#=GetPointerX()
polygon[0].p_c.y#=GetPointerY()
endif
if GetDistance#( GetPointerX(), GetPointerY(), polygon[0].p_d.x#, polygon[0].p_d.y#)<20.0
polygon[0].p_d.x#=GetPointerX()
polygon[0].p_d.y#=GetPointerY()
endif
endif
endfunction
// draw the 4 point polygon
function draw_polygon(num)
color1=MakeColor(255,0,0)
x#=polygon[num].p_d.x#
y#=polygon[num].p_d.y#
for i=1 to 4
ox#=x#
oy#=y#
// the following selection is responsible for several things. First, we need the coordinates of the current point (x#),
// then we need the next(nx#) and previous point (ox#) to get the right angle for the convex/concave calculation
select i
case 1:
x#=polygon[num].p_a.x#
y#=polygon[num].p_a.y#
nx#=polygon[num].p_b.x#
ny#=polygon[num].p_b.y#
text=polygon[num].p_a.txt
rad#=polygon[num].p_a.rad#
endcase
case 2:
x#=polygon[num].p_b.x#
y#=polygon[num].p_b.y#
nx#=polygon[num].p_c.x#
ny#=polygon[num].p_c.y#
text=polygon[num].p_b.txt
rad#=polygon[num].p_b.rad#
endcase
case 3:
x#=polygon[num].p_c.x#
y#=polygon[num].p_c.y#
nx#=polygon[num].p_d.x#
ny#=polygon[num].p_d.y#
text=polygon[num].p_c.txt
rad#=polygon[num].p_c.rad#
endcase
case 4:
x#=polygon[num].p_d.x#
y#=polygon[num].p_d.y#
nx#=polygon[num].p_a.x#
ny#=polygon[num].p_a.y#
text=polygon[num].p_d.txt
rad#=polygon[num].p_d.rad#
endcase
endselect
// draw spheres at each point
DrawEllipse( x#, y#, 10, 10, color1, color1, 1 )
// draw lines
if ox#<>0 and oy#<>0
DrawLine( ox#, oy#, x#, y#, 255, 255, 255 )
endif
// draw text at each point
if text=0
txt=CreateText(chr(64+i))
SetTextSize(txt,20)
SetTextPosition(txt,x#+10, y#+10)
// update text
if i=1 then polygon[num].p_a.txt=txt
if i=2 then polygon[num].p_b.txt=txt
if i=3 then polygon[num].p_c.txt=txt
if i=4 then polygon[num].p_d.txt=txt
else
settextstring(text,chr(64+i)+" "+str(rad#)+"°")
SetTextPosition(text,x#+10, y#+10)
endif
// calculate angles at each point
// Get first Vector
abx#=x#-nx#
aby#=y#-ny#
// Get second Vector
adx#=x#-ox#
ady#=y#-oy#
va#=sqrt(abx#^2+aby#^2)
vb#=sqrt(adx#^2+ady#^2)
scal#=abx#*adx#+aby#*ady#
rad#=ACos(scal#/(va#*vb#))
// update radius
if i=1 then polygon[num].p_a.rad#=rad#
if i=2 then polygon[num].p_b.rad#=rad#
if i=3 then polygon[num].p_c.rad#=rad#
if i=4 then polygon[num].p_d.rad#=rad#
next i
// concave or convex
insrad=polygon[num].p_a.rad#+polygon[num].p_b.rad#+polygon[num].p_c.rad#+polygon[num].p_d.rad#
if insrad=360
polygon[num].convex=1
else
polygon[num].convex=0
endif
endfunction
// distance code
Function GetDistance#( X1#, Y1#, X2#, Y2#)
Dist_X# = X1# - X2#
Dist_Y# = Y1# - Y2#
Distance# = Sqrt(Dist_X# * Dist_X# + Dist_Y# * Dist_Y#)
EndFunction Distance#
Version 2 (with simple volume hit function):
// Project: Convex or Concave
// Created: 2015-10-08
// Alex Schmidt 2015 - online-arts.de
// Convex or Concave
// set window properties
SetWindowTitle( "Convex or Concave" )
SetWindowSize( 1280, 720, 0 )
// set display properties
SetVirtualResolution( 1280, 720 )
SetOrientationAllowed( 1, 1, 1, 1 )
// define a point
type point_def
x# as float
y# as float
txt as integer
rad# as float
endtype
// define a poly with 4 points
type poly_def
p_a as point_def
p_b as point_def
p_c as point_def
p_d as point_def
convex as integer
endtype
dim polygon[0] as poly_def
// define first polygon
polygon[0].p_a.x#=600.0
polygon[0].p_a.y#=150.0
polygon[0].p_b.x#=200.0
polygon[0].p_b.y#=180.0
polygon[0].p_c.x#=80.0
polygon[0].p_c.y#=500.0
polygon[0].p_d.x#=400.0
polygon[0].p_d.y#=500.0
do
print("Convex or Concave? - Check the volume")
print("=====================================")
// user output
if polygon[0].convex=0 then print("concave (collision does not work well)")
if polygon[0].convex=1 then print("convex (collision works perfectly)")
draw_polygon(0)
handle_polygon(0)
if GetPointerReleased()=1
col=0
// ABD
col=col+check_triangle_collision(0,GetPointerX(),GetPointerY(),polygon[0].p_a.x#,polygon[0].p_a.y#,polygon[0].p_d.x#,polygon[0].p_d.y#,polygon[0].p_b.x#,polygon[0].p_b.y#)
// BDC
col=col+check_triangle_collision(0,GetPointerX(),GetPointerY(),polygon[0].p_b.x#,polygon[0].p_b.y#,polygon[0].p_d.x#,polygon[0].p_d.y#,polygon[0].p_c.x#,polygon[0].p_c.y#)
print("HIT: "+str(col))
endif
Sync()
loop
function check_triangle_collision(num,pointx#,pointy#,x1#,y1#,x2#,y2#,x3#,y3#)
` is point in front of edge 1
if (((x2#-x1#)*(PointY#-y1#))-((PointX#-x1#)*(y2#-y1#)))<0 then exitfunction 0
` is point in front of edge 2
if (((x3#-x2#)*(PointY#-y2#))-((PointX#-x2#)*(y3#-y2#)))<0 then exitfunction 0
` is point in front of edge 3
if (((x1#-x3#)*(PointY#-y3#))-((PointX#-x3#)*(y1#-y3#)))<0 then exitfunction 0
Endfunction 1
// being able to modify is acually pretty great
function handle_polygon(num)
if GetPointerState()=1
if GetDistance#( GetPointerX(), GetPointerY(), polygon[0].p_a.x#, polygon[0].p_a.y#)<20.0
polygon[0].p_a.x#=GetPointerX()
polygon[0].p_a.y#=GetPointerY()
endif
if GetDistance#( GetPointerX(), GetPointerY(), polygon[0].p_b.x#, polygon[0].p_b.y#)<20.0
polygon[0].p_b.x#=GetPointerX()
polygon[0].p_b.y#=GetPointerY()
endif
if GetDistance#( GetPointerX(), GetPointerY(), polygon[0].p_c.x#, polygon[0].p_c.y#)<20.0
polygon[0].p_c.x#=GetPointerX()
polygon[0].p_c.y#=GetPointerY()
endif
if GetDistance#( GetPointerX(), GetPointerY(), polygon[0].p_d.x#, polygon[0].p_d.y#)<20.0
polygon[0].p_d.x#=GetPointerX()
polygon[0].p_d.y#=GetPointerY()
endif
endif
endfunction
// draw the 4 point polygon
function draw_polygon(num)
color1=MakeColor(255,0,0)
x#=polygon[num].p_d.x#
y#=polygon[num].p_d.y#
for i=1 to 4
ox#=x#
oy#=y#
// the following selection is responsible for several things. First, we need the coordinates of the current point (x#),
// then we need the next(nx#) and previous point (ox#) to get the right angle for the convex/concave calculation
select i
case 1:
x#=polygon[num].p_a.x#
y#=polygon[num].p_a.y#
nx#=polygon[num].p_b.x#
ny#=polygon[num].p_b.y#
text=polygon[num].p_a.txt
rad#=polygon[num].p_a.rad#
endcase
case 2:
x#=polygon[num].p_b.x#
y#=polygon[num].p_b.y#
nx#=polygon[num].p_c.x#
ny#=polygon[num].p_c.y#
text=polygon[num].p_b.txt
rad#=polygon[num].p_b.rad#
endcase
case 3:
x#=polygon[num].p_c.x#
y#=polygon[num].p_c.y#
nx#=polygon[num].p_d.x#
ny#=polygon[num].p_d.y#
text=polygon[num].p_c.txt
rad#=polygon[num].p_c.rad#
endcase
case 4:
x#=polygon[num].p_d.x#
y#=polygon[num].p_d.y#
nx#=polygon[num].p_a.x#
ny#=polygon[num].p_a.y#
text=polygon[num].p_d.txt
rad#=polygon[num].p_d.rad#
endcase
endselect
// draw spheres at each point
DrawEllipse( x#, y#, 10, 10, color1, color1, 1 )
// draw lines
if ox#<>0 and oy#<>0
DrawLine( ox#, oy#, x#, y#, 255, 255, 255 )
endif
// draw text at each point
if text=0
txt=CreateText(chr(64+i))
SetTextSize(txt,20)
SetTextPosition(txt,x#+10, y#+10)
// update text
if i=1 then polygon[num].p_a.txt=txt
if i=2 then polygon[num].p_b.txt=txt
if i=3 then polygon[num].p_c.txt=txt
if i=4 then polygon[num].p_d.txt=txt
else
settextstring(text,chr(64+i)+" "+str(rad#)+"°")
SetTextPosition(text,x#+10, y#+10)
endif
// calculate angles at each point
// Get first Vector
abx#=x#-nx#
aby#=y#-ny#
// Get second Vector
adx#=x#-ox#
ady#=y#-oy#
va#=sqrt(abx#^2+aby#^2)
vb#=sqrt(adx#^2+ady#^2)
scal#=abx#*adx#+aby#*ady#
rad#=ACos(scal#/(va#*vb#))
// update radius
if i=1 then polygon[num].p_a.rad#=rad#
if i=2 then polygon[num].p_b.rad#=rad#
if i=3 then polygon[num].p_c.rad#=rad#
if i=4 then polygon[num].p_d.rad#=rad#
next i
// concave or convex
insrad=polygon[num].p_a.rad#+polygon[num].p_b.rad#+polygon[num].p_c.rad#+polygon[num].p_d.rad#
if insrad=360
polygon[num].convex=1
else
polygon[num].convex=0
endif
endfunction
// distance code
Function GetDistance#( X1#, Y1#, X2#, Y2#)
Dist_X# = X1# - X2#
Dist_Y# = Y1# - Y2#
Distance# = Sqrt(Dist_X# * Dist_X# + Dist_Y# * Dist_Y#)
EndFunction Distance#
Version 3: (Simple Editor)
// Project: Polygon Drawer
// Created: 2015-10-08
// Alex Schmidt 2015 - online-arts.de
// Convex or Concave
// set window properties
SetWindowTitle( "Polygon Drawer" )
SetWindowSize( 1280, 720, 0 )
// set display properties
SetVirtualResolution( 1280, 720 )
SetOrientationAllowed( 1, 1, 1, 1 )
// define a point
type point_def
x# as float
y# as float
txt as integer
rad# as float
endtype
// define a poly with 4 points
type poly_def
p_a as point_def
p_b as point_def
p_c as point_def
p_d as point_def
convex as integer
endtype
dim polygon[12] as poly_def
global max_poly as integer
global edit_mode as integer
global selected_poly as integer
global edit_doubleclick as integer
// define first polygon
rem add_polygon(600.0,150.0,200.0,180.0,80.0,500.0,400.0,500.0)
create_button(1,190,50,60,255,255,0,"New")
create_button(2,50,50,60,255,255,255,"Sel")
create_button(3,120,50,60,0,255,0,"Edit")
create_button(4,260,50,60,255,0,0,"Delete")
do
print(edit_mode)
print(str(selected_poly)+"/"+str(max_poly))
// handle hud
if GetVirtualButtonReleased(1)=1 then add_polygon(700.0,150.0,200.0,150.0,200.0,500.0,700.0,500.0)
if GetVirtualButtonReleased(2)=1 then edit_mode=0
if GetVirtualButtonReleased(3)=1 then edit_mode=1
if GetVirtualButtonReleased(4)=1 then delete_polygon()
if edit_doubleclick>0
print(edit_doubleclick)
dec edit_doubleclick
if GetPointerPressed()=1
col=0
col=col+check_triangle_collision(selected_poly-1,GetPointerX(),GetPointerY(),polygon[selected_poly-1].p_a.x#,polygon[selected_poly-1].p_a.y#,polygon[selected_poly-1].p_d.x#,polygon[selected_poly-1].p_d.y#,polygon[selected_poly-1].p_b.x#,polygon[selected_poly-1].p_b.y#)
col=col+check_triangle_collision(selected_poly-1,GetPointerX(),GetPointerY(),polygon[selected_poly-1].p_b.x#,polygon[selected_poly-1].p_b.y#,polygon[selected_poly-1].p_d.x#,polygon[selected_poly-1].p_d.y#,polygon[selected_poly-1].p_c.x#,polygon[selected_poly-1].p_c.y#)
if col>0
edit_mode=3
tepx#=GetPointerX()
tepy#=getpointerY()
endif
endif
endif
if edit_mode=3
ox#=tepx#-GetPointerX()
oy#=tepy#-getpointery()
polygon[selected_poly-1].p_a.x#=polygon[selected_poly-1].p_a.x#-ox#
polygon[selected_poly-1].p_a.y#=polygon[selected_poly-1].p_a.y#-oy#
polygon[selected_poly-1].p_b.x#=polygon[selected_poly-1].p_b.x#-ox#
polygon[selected_poly-1].p_b.y#=polygon[selected_poly-1].p_b.y#-oy#
polygon[selected_poly-1].p_c.x#=polygon[selected_poly-1].p_c.x#-ox#
polygon[selected_poly-1].p_c.y#=polygon[selected_poly-1].p_c.y#-oy#
polygon[selected_poly-1].p_d.x#=polygon[selected_poly-1].p_d.x#-ox#
polygon[selected_poly-1].p_d.y#=polygon[selected_poly-1].p_d.y#-oy#
tepx#=GetPointerX()
tepy#=GetPointerY()
endif
if GetPointerReleased()=1 and edit_mode=3 then edit_mode=0
for i=0 to max_poly-1
draw_polygon(i)
if edit_mode=1 then handle_polygon(i)
if GetPointerReleased()=1 and edit_mode=0
col=0
col=col+check_triangle_collision(i,GetPointerX(),GetPointerY(),polygon[i].p_a.x#,polygon[i].p_a.y#,polygon[i].p_d.x#,polygon[i].p_d.y#,polygon[i].p_b.x#,polygon[i].p_b.y#)
col=col+check_triangle_collision(i,GetPointerX(),GetPointerY(),polygon[i].p_b.x#,polygon[i].p_b.y#,polygon[i].p_d.x#,polygon[i].p_d.y#,polygon[i].p_c.x#,polygon[i].p_c.y#)
if col>0
selected_poly=i+1
edit_doubleclick=20
exit
else
selected_poly=0
endif
endif
next i
Sync()
loop
function delete_polygon()
if selected_poly>0
edit_mode=0
deletetext(polygon[selected_poly-1].p_a.txt)
deletetext(polygon[selected_poly-1].p_b.txt)
deletetext(polygon[selected_poly-1].p_c.txt)
deletetext(polygon[selected_poly-1].p_d.txt)
polygon.remove(selected_poly-1)
selected_poly=0
dec max_poly
endif
endfunction
function create_button(button,x,y,s,r,g,b,t$)
AddVirtualButton(button,x,y,s)
SetVirtualButtonAlpha(button,192)
SetVirtualButtonColor(button,r,g,b)
SetVirtualButtonText(button,t$)
SetVirtualButtonVisible(button,1)
endfunction
function add_polygon(ax#,ay#,bx#,by#,cx#,cy#,dx#,dy#)
polygon[max_poly].p_a.x#=ax#
polygon[max_poly].p_a.y#=ay#
polygon[max_poly].p_b.x#=bx#
polygon[max_poly].p_b.y#=by#
polygon[max_poly].p_c.x#=cx#
polygon[max_poly].p_c.y#=cy#
polygon[max_poly].p_d.x#=dx#
polygon[max_poly].p_d.y#=dy#
inc max_poly
endfunction
function check_triangle_collision(num,pointx#,pointy#,x1#,y1#,x2#,y2#,x3#,y3#)
` is point in front of edge 1
if (((x2#-x1#)*(PointY#-y1#))-((PointX#-x1#)*(y2#-y1#)))<0 then exitfunction 0
` is point in front of edge 2
if (((x3#-x2#)*(PointY#-y2#))-((PointX#-x2#)*(y3#-y2#)))<0 then exitfunction 0
` is point in front of edge 3
if (((x1#-x3#)*(PointY#-y3#))-((PointX#-x3#)*(y1#-y3#)))<0 then exitfunction 0
Endfunction 1
// being able to modify is acually pretty great
function handle_polygon(num)
if GetPointerState()=1 and selected_poly-1=num
if GetDistance#( GetPointerX(), GetPointerY(), polygon[num].p_a.x#, polygon[num].p_a.y#)<20.0
polygon[num].p_a.x#=GetPointerX()
polygon[num].p_a.y#=GetPointerY()
endif
if GetDistance#( GetPointerX(), GetPointerY(), polygon[num].p_b.x#, polygon[num].p_b.y#)<20.0
polygon[num].p_b.x#=GetPointerX()
polygon[num].p_b.y#=GetPointerY()
endif
if GetDistance#( GetPointerX(), GetPointerY(), polygon[num].p_c.x#, polygon[num].p_c.y#)<20.0
polygon[num].p_c.x#=GetPointerX()
polygon[num].p_c.y#=GetPointerY()
endif
if GetDistance#( GetPointerX(), GetPointerY(), polygon[num].p_d.x#, polygon[num].p_d.y#)<20.0
polygon[num].p_d.x#=GetPointerX()
polygon[num].p_d.y#=GetPointerY()
endif
endif
endfunction
// draw the 4 point polygon
function draw_polygon(num)
color1=MakeColor(255,0,0)
x#=polygon[num].p_d.x#
y#=polygon[num].p_d.y#
for i=1 to 4
ox#=x#
oy#=y#
// the following selection is responsible for several things. First, we need the coordinates of the current point (x#),
// then we need the next(nx#) and previous point (ox#) to get the right angle for the convex/concave calculation
select i
case 1:
x#=polygon[num].p_a.x#
y#=polygon[num].p_a.y#
nx#=polygon[num].p_b.x#
ny#=polygon[num].p_b.y#
text=polygon[num].p_a.txt
rad#=polygon[num].p_a.rad#
endcase
case 2:
x#=polygon[num].p_b.x#
y#=polygon[num].p_b.y#
nx#=polygon[num].p_c.x#
ny#=polygon[num].p_c.y#
text=polygon[num].p_b.txt
rad#=polygon[num].p_b.rad#
endcase
case 3:
x#=polygon[num].p_c.x#
y#=polygon[num].p_c.y#
nx#=polygon[num].p_d.x#
ny#=polygon[num].p_d.y#
text=polygon[num].p_c.txt
rad#=polygon[num].p_c.rad#
endcase
case 4:
x#=polygon[num].p_d.x#
y#=polygon[num].p_d.y#
nx#=polygon[num].p_a.x#
ny#=polygon[num].p_a.y#
text=polygon[num].p_d.txt
rad#=polygon[num].p_d.rad#
endcase
endselect
// draw spheres at each point
if edit_mode=1 and selected_poly-1=num then DrawEllipse( x#, y#, 10, 10, color1, color1, 1 )
// draw lines
if ox#<>0 and oy#<>0
if selected_poly-1=num
DrawLine( ox#, oy#, x#, y#, 255, 0, 0 )
else
DrawLine( ox#, oy#, x#, y#, 255, 255, 255 )
endif
endif
// draw text at each point
if text=0
txt=CreateText(chr(64+i))
SetTextSize(txt,20)
SetTextPosition(txt,-100,-100)
// update text
if i=1 then polygon[num].p_a.txt=txt
if i=2 then polygon[num].p_b.txt=txt
if i=3 then polygon[num].p_c.txt=txt
if i=4 then polygon[num].p_d.txt=txt
else
if selected_poly-1=num
settextstring(text,chr(64+i)+" "+str(rad#)+"°")
SetTextPosition(text,x#+10, y#+10)
else
SetTextPosition(text,-100, -100)
endif
endif
// calculate angles at each point
// Get first Vector
abx#=x#-nx#
aby#=y#-ny#
// Get second Vector
adx#=x#-ox#
ady#=y#-oy#
va#=sqrt(abx#^2+aby#^2)
vb#=sqrt(adx#^2+ady#^2)
scal#=abx#*adx#+aby#*ady#
rad#=ACos(scal#/(va#*vb#))
// update radius
if i=1 then polygon[num].p_a.rad#=rad#
if i=2 then polygon[num].p_b.rad#=rad#
if i=3 then polygon[num].p_c.rad#=rad#
if i=4 then polygon[num].p_d.rad#=rad#
next i
// concave or convex
insrad=polygon[num].p_a.rad#+polygon[num].p_b.rad#+polygon[num].p_c.rad#+polygon[num].p_d.rad#
if insrad=360
polygon[num].convex=1
else
polygon[num].convex=0
endif
endfunction
// distance code
Function GetDistance#( X1#, Y1#, X2#, Y2#)
Dist_X# = X1# - X2#
Dist_Y# = Y1# - Y2#
Distance# = Sqrt(Dist_X# * Dist_X# + Dist_Y# * Dist_Y#)
EndFunction Distance#