rotating a vector?

BlitzMax Forums/BlitzMax Programming/rotating a vector?

Here's a 2d vector graphics "engine" I whipped up some time ago as a quick test. It includes basic vector rotation methods which might help you out. It uses startpoint & endpoint logic to represent vectors rather than direction & lenght.

Use arrow keys to move and rotate the vector drawing around the screen. Z and X keys change the scale of the drawing on-the-fly.

SuperStrict
Graphics(600, 400) 

Local vDrawing:TDrawing = TDrawing.Create() 
vDrawing.AddVector(20, 0, - 20, 0) 
vDrawing.AddVector(20, 0, - 20, - 10) 
vDrawing.AddVector(20, 0, - 20, 10) 

Local x:Float = 50
Local y:Float = 50


Repeat
	If KeyDown(KEY_LEFT) Then vDrawing.Rotate(- 2) 
	If KeyDown(KEY_RIGHT) Then vDrawing.Rotate(2) 
	If KeyDown(KEY_UP) Then
		x = x + 2 * Cos(vDrawing.rot) 
		y = y + 2 * Sin(vDrawing.rot) 
	EndIf
	If KeyDown(KEY_Z) Then vDrawing.scale:+0.1
	If KeyDown(KEY_X) Then vDrawing.scale:-0.1 
	vDrawing.Draw(x, y) 
	Flip;Cls
Until KeyDown(KEY_ESCAPE) Or AppTerminate() 

Type TDrawing
	Field vectors:TVector[] 
	Field rot:Float
	Field scale:Float = 1
	
	Method AddVector(sx:Double, sy:Double, ex:Double, ey:Double) 
		Local vect:TVector = TVector.Create(sx, sy, ex, ey) 
		vectors = vectors[..vectors.Length + 1] 
		vectors[vectors.Length - 1] = vect
	End Method
	
	Method SetRot(r:Float) 
		rot = r
	End Method
	
	Method Rotate(theta:Float) 
		rot = rot + theta
		If rot <= 0 Then
			rot = 360 - rot
		ElseIf rot > 360 Then
			rot = rot - 360
		EndIf
	End Method
	
	Method Draw(x:Double, y:Double) 
		If Not vectors Then Return
		SetScale(1, 1) 
		SetLineWidth(1 * scale) 
		If GetLineWidth() < 1 Then SetLineWidth(1) 
		For Local v:TVector = EachIn vectors
			DrawLine(v.s.GetRotatedX(rot, scale) + x,  ..
					v.s.GetRotatedY(rot, scale) + y,  ..
					v.e.GetRotatedX(rot, scale) + x,  ..
					v.e.GetRotatedY(rot, scale) + y,  ..
					False) 
		Next
	End Method
	
	Function Create:TDrawing(_rot:Float = 0, _scale:Float = 1) 
		Local d:TDrawing = New TDrawing
		d.rot = _rot
		d.scale = _scale
		Return d
	End Function
End Type


Type TVector
	Field s:TPoint
	Field e:TPoint
	
	Method GetLength:Float() 
		Return Sqr((e.x - s.x) ^ 2 + (e.y - s.y) ^ 2) 
	End Method
	
	' returns a new copy of the vector rotated by theta
	Method GetRotatedVector:TVector(theta:Float, scale:Float = 1) 
		If theta = 0 Then Return Self
		Local v:TVector = TVector.Create( ..
						s.GetRotatedX(theta, scale),  ..
						s.GetRotatedY(theta, scale),  ..
						e.GetRotatedX(theta, scale),  ..
						e.GetRotatedY(theta, scale)) 
		Return v
	End Method
	
	' Rotates the vector around the origin permanently
	Method Rotate(theta:Float, scale:Float = 1) 
		If theta = 0 Then Return
		s.Rotate(theta, scale) 
		e.Rotate(theta, scale) 
	End Method
	
	Function Create:TVector(sx:Double, sy:Double, ex:Double, ey:Double) 
		Local v:TVector = New TVector
		v.s = TPoint.Create(sx, sy) 
		v.e = TPoint.Create(ex, ey) 
		Return v
	End Function
End Type

Type TPoint
	Field x:Double
	Field y:Double

	' returns the x coordinate rotated around the origin by theta
	Method GetRotatedX:Double(theta:Float, scale:Float = 1) 
		Return Cos(theta) * x * scale - Sin(theta) * y * scale
	End Method
	
	' returns the y coordinate rotated around the origin by theta
	Method GetRotatedY:Double(theta:Float, scale:Float = 1) 
		Return Sin(theta) * x * scale + Cos(theta) * y * scale
	End Method
	
	' Rotates the point around the origin permanently
	Method Rotate(theta:Float, scale:Float = 1) 
		x = GetRotatedX(theta) * scale
		y = GetRotatedY(theta) * scale
	End Method
	
	Function Create:TPoint(_x:Double, _y:Double) 
		Local p:TPoint = New TPoint
		p.x = _x ; p.y = _y
		Return p
	End Function
End Type