A little help with trig please.

Blitz3D Forums/Blitz3D Programming/A little help with trig please.

TartanTangerine (was Indiepath)(Posted 2005) [#1]
I want to create and n-sided polygon (sides of equal length) by specifying the start and end points only.

Does anyone have a little snippit of code that can help me?

Oh and I'm in 2d here.

Regards,

Tim.


Rob Farley(Posted 2005) [#2]
I'm a bit confused here because the startpoint will be the endpoint surely?

Anyway, here's one I knocked up that you give it x,y of the centre, a radius and how many sides...




Yan(Posted 2005) [#3]
.
[edit]Hahaha...Ah well, pointless have 2 practically identical posts.[/edit]


sswift(Posted 2005) [#4]
You'll have to specify the number of sides you want in addition to the length of one side.

Let N be the number of sides.

Calculate the length of one side:

Side_Length# = Sqr((V1x-VNx)^2 + (V1y-VNy)^2)

Assuming a counter-clockwise winding of the vertices, we know which side of the line to draw the polygon on.

We can calculate the inside angle between each segment like so:

InsideAngle# = 360.0 / Float(N)

Now you could get tricky here and try to find the center of the polygon, but I'm just gonna take the cheap way out.

Now we just need to step from the first point around the circle, incrementing our angle as we go.

Vx#[0] = First Point X
Vy#[0] = First Point Y

Vx#[N-1] = Last Point X
Vy#[N-1] = Last Point Y

For Loop = N-1 to 0 Step -1

LastSideAngle# = RayAngle#(Vx#[Loop-1], Vy#[Loop-1], Vx#[Loop], Vy#[Loop])

Vx#[Loop] = Vx[Loop-1] + Radius#*Cos(InsideAngle#)


; This function calculates the angle of a ray defined by two points in screen space.
Function RayAngle#(X1#, Y1#, X2#, Y2#)
	Return ATan2#(-(Y2#-Y1#), X2#-X1#)
End Function



I'm too tired to finish this right now. It would be easier to make that loop if you had the first and second point instead of the first and last.

The pertinent equation is this:

V2x# = V1x# + Radius#*Cos(Angle)
V2y# = V1y# + Radius#*Sin(Angle)

Calculate the angle between the first and second vertex, and then add the inside angle to that value. That is what you would input into angle in the above equation. Except you might need to subtract the inside angle instead. I'm too tired to think right now. :-)


TartanTangerine (was Indiepath)(Posted 2005) [#5]
@Rob, yeah I got that one.

Okay rather than start point and end point lets call them point 1 and point 2. So for a triangle the first two points are defined, and for a pentagon and for a hexagon etc...

Any takers?


TartanTangerine (was Indiepath)(Posted 2005) [#6]
@sswift, yeah I was thinking that - the reason for doing this is to make a simple to use level editor for GEOM (for public consumption). The Polygons will have to translate and connect to the nearest poly - ala tessellations.


Braincell(Posted 2005) [#7]
You mean point1 and point2 are points defining one line (or side) which makes up a polygon? If thats the case you will always have 2 possibilities, make those 2 points on top or on the bottom of the shape, or in fact depending on the relative angle of the two points, right or left, etc.

In other words, you need to know which side is pointing towards the center of the polygon, 1-2 or 2-1... If you get what im saying.


TartanTangerine (was Indiepath)(Posted 2005) [#8]
Lenn, these two points are defined by the nearest edge of the nearest poly.

Here is a picture to demonstrate my point



You see that the Poly I am trying to place (vertices are black circles) is not aligned to the side of the square. I can adjust the angle by hand but I want this to be automatic.

The vertices on the far right of this square will be points 1 and 2 as explained above.


big10p(Posted 2005) [#9]
Something like this what you mean?

	Graphics 800,600
	SetBuffer BackBuffer()
	
	; Set the two vertices defining the 'start' line.
	start_x# = 100
	start_y# = 300
	end_x# = 120
	end_y# = 180
	
	delta_x = end_x - start_x
	delta_y = end_y - start_y

	ang# = ATan2(delta_y,delta_x)
	side_len# = Sqr(delta_x*delta_x + delta_y*delta_y)
		
	While Not KeyHit(1)
	
		Cls

		Locate 0,0
		num_sides = Input("Enter number of sides: ")

		; Draw 'start' line in red.
		Color 255,0,0
		Line start_x,start_y,end_x,end_y
		
		; Draw remaining poly sides in white.
		Color 255,255,255
		x1 = end_x
		y1 = end_y
		d_ang# = 360.0 / num_sides
		For n = 1 To num_sides-1
			x2 = x1 + (Cos((d_ang*n) + ang) * side_len)
			y2 = y1 + (Sin((d_ang*n) + ang) * side_len)
			
			Line x1,y1,x2,y2
			
			x1 = x2
			y1 = y2
		Next
	
		VWait : Flip False
		
	Wend
	
	End



TartanTangerine (was Indiepath)(Posted 2005) [#10]
big10p, thats the baby. Thank you so much, now the GEOM owners can have thier level editor much sooner than they expected.

Cheers, Tim.