If using a 2d vector type to store the relative coords of a polygon, like this:
Type vector2d
x As Single
y As Single
End Type
Dim poly as vector2d ptr = New vector2d(n)
What would be the fastest method to rotate all the points around the poly's center point?
Something like
dim p(3) as array of vector2d
dim r(3) as array of vector2d
...
middle.x=(p(0).x + p(1).x + p(2).x)/3
middle.y=(p(0).y + p(1).y + p(2).y)/3
angle = ???
s=sin(angle)
c=cos(angle)
for i=0 to 2
dx = p(i).x - middle.x
dy = p(i).y - middle.y
r(i).x = middle.x + c * dx + s * dy
r(i).y = middle.y - s * dx + c * dy
next
That will put the rotated points in r().
Jim
Thanks, but now can you tell me why p4 (the white one) isn't where it should be?
#Include Once "crt.bi"
Type vector2d
x As Single
y As Single
End Type
Sub polydraw(byval poly as vector2d Ptr ,ByVal x as integer, y as Integer, ByVal clr As UInteger = RGB(255,255,255), scale As single = 1)
For i As Integer = 0 To 2
Line (x+(poly[i].x*scale),y+(poly[i].y)*scale)-(x+(poly[i+1].x*scale),y+(poly[i+1].y*scale)),clr
next
Line (x+(poly[3].x*scale),y+(poly[3].y)*scale)-(x+(poly[0].x*scale),y+(poly[0].y*scale)),clr
End Sub
sub polyrotate (byval orig As vector2d Ptr, byval angle as integer)
dim as vector2d r(4)
dim as single mx, my
dim as single s,c, dx, dy
mx=(orig[0].x + orig[1].x + orig[2].x + orig[3].x)/4
my=(orig[0].y + orig[1].y + orig[2].y + orig[3].y)/4
s=sin(angle)
c=cos(angle)
for i as integer = 0 to 4
dx = orig[i].x - mx
dy = orig[i].y - my
r(i).x = mx + c * dx + s * dy
r(i).y = my - s * dx + c * dy
Next
memcpy (orig, @r(0), 4*SizeOf(vector2d))
End Sub
Dim As vector2d p1(3) => {(-1,0),(0,-1),(1,0),(0,1)}
Dim as vector2d p2(3) => {(-1,0),(0,-1),(1,0),(0,1)}
Dim as vector2d p3(3) => {(-1,0),(0,-1),(1,0),(0,1)}
Dim as vector2d p4(3) => {(-1,0),(0,-1),(1,0),(0,1)}
polyrotate (@p2(0), 90)
polyrotate (@p3(0), 180)
polyrotate (@p4(0), 270)
ScreenRes 800,600,32
Dim As Single i = 0
Dim As single j = .1
While InKey = ""
ScreenLock
cls
polydraw(@p1(0), 400,300, RGB(255,0,0),150)
polydraw(@p2(0), 400,300, RGB(0,255,0),150)
polydraw(@p3(0), 400,300, RGB(0,0,255),150)
polydraw(@p4(0), 400,300, ,150)
ScreenUnLock
Wend
wait..
is that code for degrees or radians?
Radians, so you'd need to multiply your angles by pi/180, or about 0.01745
s = sin(angle*0.01745)
c = cos(angle*0.01745)
That way all the 4 diamonds will end up on top of one another.
Jim
heh, was playing around with this and got completely off-track from what I was originally planning
#Include Once "crt.bi"
Type vector2d
x As Single
y As Single
End Type
Sub polydraw(byval poly as vector2d Ptr ,ByVal x as integer, y as Integer, ByVal clr As UInteger = RGB(255,255,255), scale As single = 1)
For i As Integer = 0 To 2
Line (x+(poly[i].x*scale),y+(poly[i].y)*scale)-(x+(poly[i+1].x*scale),y+(poly[i+1].y*scale)),clr
next
Line (x+(poly[3].x*scale),y+(poly[3].y)*scale)-(x+(poly[0].x*scale),y+(poly[0].y*scale)),clr
End Sub
Sub polydrawpoints(byval poly as vector2d Ptr ,ByVal x as integer, y as Integer, ByVal clr As UInteger = RGB(255,255,255), scale As single = 1)
For i As Integer = 0 To 3
pset (x+(poly[i].x*scale),y+(poly[i].y)*scale),clr
next
End Sub
sub polyrotate (byval orig As vector2d Ptr, byval angle as integer)
dim as vector2d r(4)
dim as single mx, my
dim as single s,c, dx, dy
mx=(orig[0].x + orig[1].x + orig[2].x + orig[3].x)/4
my=(orig[0].y + orig[1].y + orig[2].y + orig[3].y)/4
s=sin(angle*0.01745)
c=cos(angle*0.01745)
for i as integer = 0 to 4
dx = orig[i].x - mx
dy = orig[i].y - my
r(i).x = mx + c * dx + s * dy
r(i).y = my - s * dx + c * dy
Next
memcpy (orig, @r(0), 4*SizeOf(vector2d))
End Sub
Dim As vector2d p1(3) => {(-2,0),(0,-2),(2,0),(0,2)}
Dim as vector2d p2(3) => {(-2,0),(0,-2),(2,0),(0,2)}
Dim as vector2d p3(3) => {(-2,0),(0,-2),(2,0),(0,2)}
Dim as vector2d p4(3) => {(-2,0),(0,-2),(2,0),(0,2)}
polyrotate (@p2(0), 22.5)
polyrotate (@p3(0), 45)
polyrotate (@p4(0), 67.5)
#Define swidth 600
#Define sheight 600
ScreenRes swidth,sheight,32
Dim As Single i = 0
Dim As single j = .4
Dim As Single r1,r2,r3,r4
r1 = Rnd*20
r2 = Rnd*20
r3 = Rnd*20
r4 = Rnd*20
Dim As Integer counter
While InKey = ""
ScreenLock
'Cls
polydrawpoints(@p1(0), swidth/2,sheight/2, RGB(255,rnd*255,0),i)
polydrawpoints(@p2(0), swidth/2,sheight/2, RGB(0,255,rnd*255),i)
polydrawpoints(@p3(0), swidth/2,sheight/2, RGB(rnd*255,0,255),i)
polydrawpoints(@p4(0), swidth/2,sheight/2, RGB(i,i,i),i)
ScreenUnLock
i += j
If i>=255 Then i=0
polyrotate (@p1(0), r1)
polyrotate (@p2(0), r2)
polyrotate (@p3(0), r3)
polyrotate (@p4(0), r4)
counter += 1
If counter >= 250000 Then
counter = 0
r1 = (Rnd*360) - (Rnd*360)
r2 = (Rnd*360) - (Rnd*360)
r3 = (Rnd*360) - (Rnd*360)
r4 = (Rnd*360) - (Rnd*360)
EndIf
Wend
Looks cool.
Good job Merick, K+ for posting the code.