Draw n-gon problem

BlitzMax Forums/BlitzMax Programming/Draw n-gon problem

Ryan Burnside(Posted 2006) [#1]
Ok I'm trying to writ my own draw polygon command.
It takes the sidelength as a parameter and the number of sides and SHOULD produce a ngon of the correct number of sides.

It works great with numbers like 5,6 but when I use the number 16, the angles are off and they are a missing side.
it makes use of this command which findsthe radius of the polygone:
Function poly_radius#(sidelength:Float,num_sides:Float)
		Local r:Float = sidelength /(2*Sin(180°/num_sides))
		Return r
End Function

Function draw_ngon(x#,y#,numsides%,sidelength#)
	Local small_angle# =360/numsides
	Local radius#=poly_radius(sidelength,numsides)
	
		For Local i=0 To numsides
		DrawLine x+Sin(i*small_angle)*radius,y-Cos(i*small_angle)*radius,x+Sin(i*small_angle+small_angle)*radius,y-Cos(i*small_angle+small_angle)*radius 
		Next
End Function



H&K(Posted 2006) [#2]
360/numsides is an int division. Change to 360.0/numsides
and in the for loop numsides-1 (otherwise you are drawing the first line twice


Ryan Burnside(Posted 2006) [#3]
Ah so in BASIC you need to denote floats by adding the ".0" to the end?


H&K(Posted 2006) [#4]
If you have an int int division, but you want a float result, then yes
If you had
global fullcircle:float = 360
then no

In Basic is you want a float constant then .0


neilo(Posted 2006) [#5]
Function poly_radius#(sidelength:Float,num_sides:Float)
		Local r:Float = sidelength /(2.0*Sin(180.0/num_sides))
		Return r
End Function

Function draw_ngon(x#,y#,numsides%,sidelength#)
	Local small_angle# =360.0/Float(numsides)
	Local start_angle#=0
	Local radius#=poly_radius(sidelength,numsides)
	
		For Local i=0 To numsides-1
		DrawLine x+Sin(start_angle)*radius,y-Cos(start_angle)*radius,x+Sin(start_angle+small_angle)*radius,y-Cos(start_angle+small_angle)*radius 
		start_angle:+small_angle
		Next
		Flip
		
End Function

Graphics 640,480
draw_ngon 100,100,16,32
While Not KeyHit(KEY_ESCAPE)
Wend



Two things:
You're drawing one too many sides.

You're also depending upon multiplications to work out points, which generally is a bad idea. Depending upon the floating point errors, you'll overshoot or undershoot the final value. Accumulate the starting angle, rather than calculating it.


H&K(Posted 2006) [#6]
@neilo, wouldnt you be better to store the end point values in two locals, so as not to need to calculate them twice?


neilo(Posted 2006) [#7]
@H&K,

Yup; good call.


Ryan Burnside(Posted 2006) [#8]
Ok thanks guys.