Ooops
March 05, 2021, 07:19:18 AM

Author Topic: [bb] Filled Rotated Ellipses by JBR [ 1+ years ago ]  (Read 446 times)

Offline BlitzBot

[bb] Filled Rotated Ellipses by JBR [ 1+ years ago ]
« on: June 29, 2017, 12:28:39 AM »
Title : Filled Rotated Ellipses
Author : JBR
Posted : 1+ years ago

Description : Calculates 90 points on the ellipse, then rotates them, then calculates the left & right x coordinate for each scanline of the ellipse. Then I use Rect to draw the line between.
I use a very fast DrawLine function - can't remember where I got it.
I get around 300ms for 1000 ellipses, but if you edit out the Rect I get around 30ms - It is the Rect that takes the time.


Code :
Code: BlitzBasic
  1. ; SPEEDY ROTATED ELLIPSE PLOTTING
  2.  
  3. Graphics3D 800,600,32,2
  4. SetBuffer BackBuffer()
  5.  
  6. Global G_Screen_Width = GraphicsWidth()
  7. Global G_Screen_Hight = GraphicsHeight()
  8.  
  9. Dim a_x%(90), a_y%(90), left_side%(G_Screen_Hight-1), rite_side%(G_Screen_Hight-1)
  10.  
  11.  
  12. Repeat
  13.  
  14.         Cls
  15.        
  16.         G_Angle# = Rnd(0,360)
  17.                
  18.         time = MilliSecs()
  19.  
  20.         For ellipse = 1 To 1000
  21.                 create_ellipse( 0,0, 100.0, 50.0, G_Angle#, 255,0,255 )
  22.         Next
  23.        
  24.         time = MilliSecs()-time
  25.  
  26.         Flip
  27.        
  28.         Color 255,255,255
  29.         Text 0,0,"Time to draw 1000 :"+time+" millisecs"
  30.         Text 0,12,"Press Space"
  31.         Flip
  32.         WaitKey()
  33.                
  34. Until KeyDown(1)
  35.  
  36. Flip
  37. FlushKeys()
  38. WaitKey()
  39. End
  40.  
  41.  
  42.  
  43.  
  44.  
  45.  
  46. ;-----------------------------------------------------------------------------------------
  47. Function create_ellipse( centre_x#, centre_y#, radius_x#, radius_y#, angle#, red,gre,blu )
  48.  
  49.         Local cos_a# = Cos( angle# )
  50.         Local sin_a# = Sin( angle# )
  51.        
  52.         For angle# = 0 To 90
  53.                 Local x# = radius_x# * Cos(angle#*4.0)                  ; simple ellipse
  54.                 Local y# = radius_y# * Sin(angle#*4.0)
  55.                
  56.                 Local rot_x# = (x#*cos_a#) - (y#*sin_a#)                ; rotated ellipse
  57.                 Local rot_y# = (x#*sin_a#) + (y#*cos_a#)
  58.                
  59.                 a_x%( angle# ) = G_Screen_Width/2 + centre_x# + rot_x#          ; adjusted for origin in middle of screen
  60.                 a_y%( angle# ) = G_Screen_Hight/2 + centre_y# + rot_y#
  61.         Next
  62.  
  63.         For i = 0 To G_Screen_Hight-1                                   ; init the left/rite sides to impossible values
  64.                 left_side(i) = 1000000
  65.                 rite_side(i) = -1000000
  66.         Next
  67.        
  68.         For lline = 0 To 90-1                                                   ; draw the lines
  69.                 Local x0 = a_x%(lline)
  70.                 Local y0 = a_y%(lline)
  71.                 Local x1 = a_x%(lline+1)
  72.                 Local y1 = a_y%(lline+1)
  73.                
  74.                 If x0<0 Then x0=0                                                       ; clipping left/top
  75.                 If y0<0 Then y0=0
  76.                 If x1<0 Then x1=0
  77.                 If y1<0 Then y1=0
  78.                
  79.                 If x0>=G_Screen_Width Then x0=G_Screen_Width-1          ;clipping rite/bottom
  80.                 If y0>=G_Screen_Hight Then y0=G_Screen_Hight-1
  81.                 If x1>=G_Screen_Width Then x1=G_Screen_Width-1
  82.                 If y1>=G_Screen_Hight Then y1=G_Screen_Hight-1
  83.  
  84. ;               Function DrawLine(x0, y0, x1, y1)
  85.                 Local dx,dy,sx,sy,err,e2
  86.                 dx = Abs(x1-x0)
  87.                 dy = Abs(y1-y0)
  88.                 If x0 < x1 Then sx = 1 Else sx = -1
  89.                 If y0 < y1 Then sy = 1 Else sy = -1
  90.                 err = dx-dy
  91.  
  92.                 Repeat
  93.                         If x0 < left_side(y0) Then left_side(y0) = x0
  94.                         If x0 > rite_side(y0) Then rite_side(y0) = x0
  95.                        
  96.                         If x0 = x1 And y0 = y1 Exit
  97.                         e2 = 2*err
  98.                         If e2 > -dy Then
  99.                                 err = err - dy
  100.                                 x0 = x0 + sx
  101.                         End If
  102.                         If e2 <  dx Then
  103.                                 err = err + dx
  104.                                 y0 = y0 + sy
  105.                         End If
  106.                 Forever
  107.  
  108.         Next
  109.        
  110.         Color red,gre,blu
  111.  
  112.         For scan_line = 0 To G_Screen_Hight-1                   ; now scan the lines
  113.                 Local x_left = left_side(scan_line)
  114.                 Local x_rite = rite_side(scan_line)
  115.                 Local width  = x_rite-x_left
  116.                
  117.                 If width > 0 Then
  118.                         Rect x_left, scan_line, width, 1
  119.                 EndIf
  120.  
  121.         Next
  122.        
  123. End Function


Comments : none...

 

SimplePortal 2.3.6 © 2008-2014, SimplePortal