isosceles trapezoid circle

Blitz3D Forums/Blitz3D Programming/isosceles trapezoid circle

MusicianKool(Posted 2012) [#1]
I got that to work, now i need it trapezoids in cube like form to make a sphere.[<- not doing that any more]



Last edited 2012

Last edited 2012


MusicianKool(Posted 2012) [#2]
How can a circular snap to grid integrate with the above code, were each snap is done in real-time, so i do not have to create objects to create the above circle.

Also, how do i separate each layer so that each trapezoid is closer to that of a square, meaning it doesn't look like a rectangle at any layer.

Last edited 2012


Midimaster(Posted 2012) [#3]
could you please descripe more detailed what you want to do? Perhaps a picture would help?

what do you mean with "snap"?, Which "grid"? Are you talking about mouse?

How should look "closer to square"? Same size of all trapezoids in the whole circle? Or same size within the same layer?

Do you need it for 2D or 3D? What is your target with this code?

Last edited 2012


MusicianKool(Posted 2012) [#4]
well i got most of it figured out, all that is left is to adjust the snap outward so that the farther the distance from the center the larger the next snap will be so that the relative size of the bases and sides are as close to the same as possible, so that it doesn't look squished.

here is what i have so far.




MusicianKool(Posted 2012) [#5]
k, my problem is that the dot should stay in the center of the trapezoid. I guess what i need to know is how to find a triangle from 2 angles and a length, i think. cause when i call construct_trap(angle,distance,cx,cy) i can find the surrounding angles, by adding half the snap value, but the distance isn't correct for each corner of the trapezoid, i think. any help would be awesome.




Floyd(Posted 2012) [#6]
Here's is the essence of what I think is the problem; find the appropriate distance for a point x,y and various angles. I worked it out on paper as follows:

Step 1 ( you have already done this step )

Draw the point x,y and the ray from the center to the point.
Determine and draw the two rays on either side of the point.

Step 2
 
Draw the "mid ray" bisecting these two sides
Draw the perpendicular line from the point to this mid ray.
Determine the distance of the intersection point from the center.

Step 3
Extend the perpendicular line from Step 2 until it hits the sides.
Determine the length of these new side lines.


The lengths (dMid and dSide) of the newly constructed lines are easily derived from the right triangles of steps 2 and 3.

Here is a small test program illustrating the procedure. At the end dSide is the length of the two white sides. Use this to construct the trapezoid, rather than the original dPoint.

Graphics 800, 600, 0, 2
SetBuffer FrontBuffer()

side1_angle# = 10
side2_angle# = 60
half_angle#  = (side2_angle - side1_angle) / 2
mid_angle# = (side1_angle + side2_angle) / 2

x# = 500
y# = 200

; Step 1

Color 255,255,255
Text 20,500,"Step 1"

Color 0,255,0
Oval x-3,y-3, 6,6
Line 0,0, x,y

Color 80,80,80
Line 0,0, Cos(side1_angle) * 1000, Sin(side1_angle) * 1000
Line 0,0, Cos(side2_angle) * 1000, Sin(side2_angle) * 1000

Delay 5000

; Step 2

Color 255,255,255
Text 20,530,"Step 2"

Color 80,80,0
;Line 0,0, Cos(side1_angle + half_angle) * 1000, Sin(side1_angle + half_angle) * 1000
Line 0,0, Cos(mid_angle) * 1000, Sin(mid_angle) * 1000
dPoint# = Sqr( x*x + y*y )

point_angle# = ATan2( y, x )
dMid# = dPoint * Cos( point_angle - mid_angle )

Color 255,255,0
Line 0,0, Cos(mid_angle) * dMid, Sin(mid_angle) * dMid

Color 0,80,0
Line x, y,    Cos(mid_angle) * dMid, Sin(mid_angle) * dMid

Delay 5000

; Step 3

Color 255,255,255
Text 20,560,"Step 3"

dSide# = dMid / Cos( half_angle )

Color 255,255,255

Line 0,0, Cos(side1_angle) * dSide, Sin(side1_angle) * dSide
Line 0,0, Cos(side2_angle) * dSide, Sin(side2_angle) * dSide

Color 0,80,0

Line Cos(side1_angle) * dSide, Sin(side1_angle) * dSide,  Cos(side2_angle) * dSide, Sin(side2_angle) * dSide 

WaitKey



MusicianKool(Posted 2012) [#7]
Thanks Floyd, but I didn't quite understand what you were describing. But I did figure it out using the method to solve triangle type AAS. which is very simple because each angle is pretty much given by 360/segs and 90, all i needed to do is plug these angle's in as well as the length of a side into the sine law and voila , done.

Now the second part of my question, has to deal with trapezoid thickness. I have something that is close to what I desire, but it's not perfect. I want the snap to expand so that each trapezoid is as close to square as possible, if that makes sense, and to snap at these said gaps. what i have now snaps correctly but the ratio of base's to the trapezoid height still looks rectangular. Also there seems to be a correlation between the number of segments the circle is comprised of and this ratio of base's to height. anyway the code.


Last edited 2012


Midimaster(Posted 2012) [#8]
something like this?

Graphics 800,600
SetBuffer BackBuffer()
Radius#=100
Sectors#=36
MiddleX#=300
MiddleY#=300
Repeat
	Length#=2*Pi*Radius
	Part#=Length/Sectors
	Print length + " " + part
	For i=0 To 360 Step 10
		xIn#=Sin(i)*Radius
		YIn#=Cos(i)*Radius
		xOut#=Sin(i)* (Radius+Part)
		yOut#=Cos(i)* (Radius+Part)
		Line MiddleX+xIn, MiddleY+yIn, MiddleX+xOut, MiddleY+yOut
		xNext#=Sin(i+10)*Radius
		YNext#=Cos(i+10)*Radius
		Line MiddleX+xIn, MiddleY+yIn, MiddleX+xNext, MiddleY+yNext
	Next
	Flip 1
	
	Delay 1000
	Radius= Radius+Part
Until KeyHit(1)



Last edited 2012


MusicianKool(Posted 2012) [#9]
@Midimaster: Well, yes and no... You have the correct ratio that I want, but I would like for it to work with a changeable number of sectors. ie.. 1600 sectors or more or less.


Midimaster(Posted 2012) [#10]
there are only a few step to complete variable parameters.

I did this example to ask, whether this is the design you are looking for:

"if distance from the circle center rises, also 'size of the rings' rises, but number of sectors keep the same in all rings"


so feel free to enter a number of sectors here:

Graphics 800,600
SetBuffer BackBuffer()
Radius#=100
Sectors#=90
AnglePerSector#=360.0/Sectors ;new!
MiddleX#=300
MiddleY#=300
Repeat
	Length#=2*Pi*Radius
	Part#=Length/Sectors
	Print length + " " + part
	i=0
	While i<360
		i=i+AnglePerSector ;new
		xIn#=Sin(i)*Radius
		YIn#=Cos(i)*Radius
		xOut#=Sin(i)* (Radius+Part)
		yOut#=Cos(i)* (Radius+Part)
		Line MiddleX+xIn, MiddleY+yIn, MiddleX+xOut, MiddleY+yOut
		xNext#=Sin(i+AnglePerSector)*Radius ;new
		YNext#=Cos(i+AnglePerSector)*Radius ;new
		Line MiddleX+xIn, MiddleY+yIn, MiddleX+xNext, MiddleY+yNext
	Wend
	Flip 1
	
	Delay 300
	Radius= Radius+Part
Until KeyHit(1)



MusicianKool(Posted 2012) [#11]
@MidiMaster: very good, that helped out a lot! Thank you.

Thank you both!

Final code:


Last edited 2012

Last edited 2012


Midimaster(Posted 2012) [#12]
there is a mistake in your code: the rectangle are not 100% squares. Hasn't this been your target?

I will have a look on the code...

well here is a sample,that shows the problem more dramatic (because of only 12 segments). And you will see my solution in yellow dots:

Graphics3D 800,300,32,2
SetBuffer BackBuffer()

Global GW# = GraphicsWidth()/2
Global GH# = GraphicsHeight()/2

Local px# = 50
Local py# = 0
Global seg# = 12

Global segA# = 360/seg

Global MaxLayers = 500
Dim part#(MaxLayers)
Local LStep = 1
Global Radius# = 1

For j = 1 To MaxLayers
	Local length#=2*Pi*Radius
	part(j)=length/seg
	Radius = Radius + part(j)
Next

Radius = 1

While Not KeyHit(1)
	Local ms1 = MilliSecs()
	Cls
	Color 255,0,0
	;circular snap
	Local Ang# = (Angle2D(px,py,MouseX()-GW,MouseY()-GH))
	Local ang1# = Floor((Ang / segA)+.5)*segA
	
;	Oval px+GW+(Sin(ang1)*Radius-3),py+GH+(Cos(ang1)*Radius-3),3,3,1
	
	
	;distance from circle center
	Local dis# = Distance(px,py,MouseX()-GW,MouseY()-GH) 
	
	Radius#=0 
	For lstep=0 To 999
		Radius=Radius+part(lStep)
		If Radius>Dis Then Exit
	Next
	Radius=Radius-part(lstep)/2
	
	DebugLog lstep + " " + dist + " " + radius + " " + ang1
	
	Construct_Trap((part(LStep-1)+part(lStep))/2,ang1#,Radius,px,py)
	Color 255,255,0
	Oval px+GW+(Sin(ang1)*Radius-3),py+GH+(Cos(ang1)*Radius-3),6,6,1
	Radius=Radius-part(lstep)/2
	Oval px+GW+(Sin(ang1-segA/2)*Radius-1),py+GH+(Cos(ang1-segA/2)*Radius-1),3,3,1
	Oval px+GW+(Sin(ang1+segA/2)*Radius-1),py+GH+(Cos(ang1+segA/2)*Radius-1),3,3,1
	Oval px+GW+(Sin(ang1+segA/2)*(Radius+part(lstep))-1),py+GH+(Cos(ang1+segA/2)*(Radius+part(lstep))-1),3,3,1
	Oval px+GW+(Sin(ang1-segA/2)*(Radius+part(lstep))-1),py+GH+(Cos(ang1-segA/2)*(Radius+part(lstep))-1),3,3,1
	
	
	;If dis >= Radius+ (part(LStep)/2) Then LStep = LStep + 1:Radius = Radius + part(LStep)
	;If dis <= Radius- part(LStep)/2 Then Radius = Radius - part(LStep):LStep= LStep - 1
	
	
	Locate 0,0
	Print (MilliSecs()-ms1)
	Flip
Wend

Function Construct_Trap(snap#,a#,d#,px#,py#)
	;d = length of side c
	
	Local x# = px + GW
	Local y# = py + GH
	
	Local as# = segA
	
	Local a1# = as/2  ;angle A
	Local b1# = 90    ;angle B
	Local c1# = 180-(a1+b1);angle C
	
	;use the sine law to find the length of side a
	Local l1# = (d *Sin(b1))/Sin(c1)
	
	Local ad# = snap/2
	
	Line x+Sin(a-a1)*(l1-ad),y+Cos(a-a1)*(l1-ad),x+Sin(a+a1)*(l1-ad),y+Cos(a+a1)*(l1-ad)
	Line x+Sin(a-a1)*(l1+ad),y+Cos(a-a1)*(l1+ad),x+Sin(a+a1)*(l1+ad),y+Cos(a+a1)*(l1+ad)
	Line x+Sin(a-a1)*(l1-ad),y+Cos(a-a1)*(l1-ad),x+Sin(a-a1)*(l1+ad),y+Cos(a-a1)*(l1+ad)
	Line x+Sin(a+a1)*(l1-ad),y+Cos(a+a1)*(l1-ad),x+Sin(a+a1)*(l1+ad),y+Cos(a+a1)*(l1+ad)
	
End Function

Function Angle2D#( x1#,y1#,x2#,y2# )
	Return 90-ATan2(y2-y1,x2-x1)
End Function


Function Distance#(x#,y#,x2#,y2#)
	Return Sqr((x#-x2#)*(x#-x2#)+(y#-y2#)*(y#-y2#))
End Function


Last edited 2012


MusicianKool(Posted 2012) [#13]
oh yea, simple enough fix though:

currently:
Construct_Trap(part(LStep),ang1,Radius,px,py)

fix:
Construct_Trap(part(LStep+1),ang1,Radius,px,py)