Dark Bit Factory & Gravity

PROGRAMMING => Freebasic => Topic started by: Merick on September 25, 2009

Title: fast rotation?
Post by: Merick on September 25, 2009
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?
Title: Re: fast rotation?
Post by: Jim on September 25, 2009
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
Title: Re: fast rotation?
Post by: Merick on September 25, 2009
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?
Title: Re: fast rotation?
Post by: Jim on September 25, 2009
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
Title: Re: fast rotation?
Post by: Merick on September 26, 2009
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
Title: Re: fast rotation?
Post by: rdc on September 26, 2009
Looks cool.
Title: Re: fast rotation?
Post by: Shockwave on September 26, 2009
Good job Merick, K+ for posting the code.