Page 1 of 1

Moving Lines -Make very cool moving lines and boxes

Posted: Sat Nov 05, 2016 9:58 pm
by walbus
Looking, very cool things we can do with a Bresenham line !

And this is only a little base code !

Many other things are available !

Code: Select all

Procedure Linie(x.i, y.i, xx.i, yy.i, shift.a, color.l, lr.i)
   
  ; Achtung Plot unterstützt kein Clipping
  
  ; Idee und coding - Werner Albus - www.nachtoptik.de
  ; Linien Algorithmus übernommen aus einem Sample von Udo Kessler
   
   Protected a.i, dx.i, dy.i, addval.i = 1
   Protected *plotX.Integer = @xx, *plotY.Integer = @yy
   
   If Abs(x - xx) <= Abs(y - yy) ; Winkel größer 45°
      Swap x, y
      Swap xx, yy
      *plotX = @yy
      *plotY = @xx
   EndIf
      
   If x < xx
      Swap x, xx
      Swap y, yy
   EndIf
   
   If y < yy
      y = 2 * yy - y
      addval = -1
   EndIf
   
   dy = 2 * (y - yy)
   a  = x - xx
   dx = 2 * a
   
   While xx <= x
      
      If shift & 1
         Plot(*plotX\i, *plotY\i, color)
      EndIf
      
      If lr
         shift = (shift << 1) | ((shift >> 7) & $7f)
      Else
         shift = ((shift >> 1) & $7F) | (shift << 7)
      EndIf
      
      xx + 1
      a - dy
      If a <= 0
         a + dx
         yy + addval
      EndIf
   Wend
   
EndProcedure

;-------------------------------------------

Procedure Liniego(x.i, y.i, xx.i, yy.i, color.l, move.i, shift.a, lr.i)
   
  For i=0 To move
  shift = (shift << 1) | ((shift >> 7) & $7f)  
  Next i

  Linie(x, y, xx, yy, shift, color, lr)     

EndProcedure

;-------------------------------------------

Procedure Boxgo(x.i, y.i, xx.i, yy.i, color.l, move.i, shift.a, lr.i)

  xx - 1 : yy - 1
  
 If lr
   Liniego(x, y, x + xx, y, color, move, shift, 1)
   Liniego(x + xx, y, x + xx, y + yy, color, move, shift, 1)
   Liniego(x, y + yy, x + xx, y + yy, color, move, shift, 0)
   Liniego(x, y + yy, x, y, color, move, shift, 0)
  Else
   Liniego(x, y, x + xx, y, color, move, shift, 0)
   Liniego(x + xx, y, x + xx, y + yy, color, move, shift, 0)
   Liniego(x, y + yy, x + xx, y + yy, color, move, shift, 1)
   Liniego(x, y + yy, x, y, color, move, shift, 1)
 EndIf
   
EndProcedure

; --------Loop-----------------------------

ExamineDesktops()

If OpenWindow (0, DesktopWidth(0) / 2 - 200, DesktopHeight(0) / 2 - 250, 500, 250, "")
   
   CanvasGadget(0, 0, 0, 500 , 400)
   AddWindowTimer(0, 0, 40)
   
   xx=3 : yy=2

   Repeat
      Select WaitWindowEvent()
         Case #PB_Event_CloseWindow:
            Break
         
          Case #PB_Event_Timer
                    
           x+xx : If x>491 : xx=-3 : EndIf
                  If x<3   : xx=3  : EndIf

           y+yy : If y>241 : yy=-3 : EndIf
                  If y<3   : yy=3  : EndIf
            
              If StartDrawing(CanvasOutput(0))
                  Box   (0, 0, 500, 250, $FFFFFF)
                  DrawingMode(#PB_2DDrawing_Outlined) ; Zeichnen von Flächen erfolgt nicht ausgefüllt
                  
                  Box (184, 104, 132, 32, $FF)
                  Box (185, 105, 130, 30, $FF)
                  Box (186, 106, 128, 28, $FF)
                  
                 If swapp<50
                  Boxgo (184, 104, 132, 32, $FFFF00, move, %11110000,1)
                  Boxgo (185, 105, 130, 30, $FFFF00, move, %11110000,1)
                  Boxgo (186, 106,  128, 28,$FFFF00, move, %11110000,1)
                   Else
                  Boxgo (184, 104, 132, 32, $00FFFF, move, %11110000,0)
                  Boxgo (185, 105, 130, 30, $00FFFF, move, %11110000,0)
                  Boxgo (186, 106,  128, 28,$00FFFF, move, %11110000,0)
                 EndIf
                
                  Boxgo (174, 94, 152, 52, $FF0000, move, %00100011,0)
                  Boxgo (175, 95, 150, 50, $FF0000, move, %00100011,0)
                  Boxgo (176, 96, 148, 48, $FF0000, move, %00100011,0)
                  
                  Boxgo (164, 84, 172, 72, $FF, move, %00100111,1)
                  Boxgo (165, 85, 170, 70, $FF, move, %00100111,0)
                  Boxgo (166, 86, 168, 68, $FF, move, %00100111,1)
                  
                  Boxgo (154, 74, 192, 92, $FF, move, %10111111,0)
                  Boxgo (155, 75, 190, 90, $FF, move, %00110011,0)
                  Boxgo (156, 76, 188, 88, $FF, move, %11111101,0)
                  
                  Boxgo (148, 68, 204, 104, $0 , move, %11100110,1)
                  Boxgo (144, 64, 212, 112, $0 , move, %00111111,0)
                  Boxgo (140, 60, 220, 120, $0 , move, %00110011,1)

                  Boxgo (144, 50, 212, 2, $32CD32 , move, %00111111,0)
                  Boxgo (143, 49, 214, 4, $32CD32 , move, %00110011,1)
                  Boxgo (142, 48, 216, 6, $32CD32 , move, %00111111,0)
                  
                  Boxgo (2+x, 2+y, 4, 4, $32CD32 , move, %00111111,1)
                  Boxgo (1+x, 1+y, 6, 6, $32CD32 , move, %00111111,1)
                  Boxgo (0+x, 0+y, 8, 8, $32CD32 , move, %00111111,1)
                  
                  liniego(144,40,250,10,$FF, move,%00111111, 1)
                  liniego(144,40,250,11,$FF, move,%00111111, 1)
                  liniego(144,40,250,12,$FF, move,%00111111, 1)
                  liniego(250,10,356,40,$FF, move,%00111111, 0)
                  liniego(250,11,356,40,$FF, move,%00111111, 0)
                  liniego(250,12,356,40,$FF, move,%00111111, 0)

                StopDrawing()
              EndIf
              
                   move +1 ; Animations Counter für bewegte Linien
                   If move >7 : move = 0 : EndIf
                   
                   swapp +1 ; Animations Counter für bewegte Linien
                   If swapp>100 : swapp= 0 : EndIf
                   

      EndSelect
      
   ForEver
   
EndIf

Re: Bresenham Line -make very cool moving lines and boxes

Posted: Sun Nov 06, 2016 12:51 am
by netmaestro
Very nice, thanks for sharing it. I think I can use it for the project I'm working on right now so the timing is good for me. Great work! I'm a fan of presentations with a difference and I'm always on the lookout for cool animations that can be embedded into otherwise-boring gui's that do a job of some kind or other and jazz them up a bit.

Re: Bresenham Line -make very cool moving lines and boxes

Posted: Sun Nov 06, 2016 2:46 am
by electrochrisso
Good coding, efficient and use very little CPU, thanks for sharing. :)

Re: Bresenham Line -make very cool moving lines and boxes

Posted: Sun Nov 06, 2016 2:52 am
by Mistrel
Retro! :D

Re: Bresenham Line -make very cool moving lines and boxes

Posted: Sun Nov 06, 2016 9:09 am
by walbus
Many thanks netmaestro, electrochrisso and Mistrel for your friendly words.

It is simple the best for making selection rectangles in pictures

To time i use it in the QAES picture steganographie for making progressbars with moving arrows

The code you can simple optimize a little with this little assembler commands, as sample :

Code: Select all

EnableASM
      If lr
       ROL shift, 1 
       ;  shift = (shift << 1) | ((shift >> 7) & $7f)
        Else
       ROR shift, 1 
        ; shift = ((shift >> 1) & $7F) | (shift << 7)
      EndIf
Best regards werner

Re: Bresenham Line -make very cool moving lines and boxes

Posted: Sun Nov 06, 2016 10:34 am
by Lunasole
Interesting. There also are much more uses for it -- for example, years ago I've used bresenham in pathfinding algorithm, as well as collisions detection, not saying about it deepth modifications using random factors to form some gfx-effects.
Generally I can say the more simple and basical is algorithm, the more interesting usage cases it has and more modifications you can make ^^ If just remember cell automates.... it's not strange that in past some hackers played with them most of their lifetime, lol

Re: Bresenham Line -make very cool moving lines and boxes

Posted: Sun Nov 06, 2016 7:24 pm
by Mistrel
That's interesting. I hadn't considered its application in pathfinding and collision. You could probably apply it to ray casting as well.

Re: Bresenham Line -make very cool moving lines and boxes

Posted: Mon Nov 07, 2016 8:12 am
by walbus
Here a rotate 16 Bit version

Code: Select all

Procedure Linie(x.i, y.i, xx.i, yy.i, shift.u, color.l, lr.i)
   
  ; Achtung Plot unterstützt kein Clipping
  
  ; Idee und coding - Werner Albus - www.nachtoptik.de
  ; Linien Algorithmus übernommen aus einem Sample von Udo Kessler
   
   Protected a.i, dx.i, dy.i, addval.i = 1
   Protected *plotX.Integer = @xx, *plotY.Integer = @yy
   
   If Abs(x - xx) <= Abs(y - yy) ; Winkel größer 45°
      Swap x, y
      Swap xx, yy
      *plotX = @yy
      *plotY = @xx
   EndIf
      
   If x < xx
      Swap x, xx
      Swap y, yy
   EndIf
   
   If y < yy
      y = 2 * yy - y
      addval = -1
   EndIf
   
   dy = 2 * (y - yy)
   a  = x - xx
   dx = 2 * a
   
   While xx <= x
      
      If shift & 1
         Plot(*plotX\i, *plotY\i, color)
      EndIf
      
      If lr
         shift = (shift << 1) | ((shift >> 15) & $7fff)
      Else
         shift = ((shift >> 1) & $7fff) | (shift << 15)
      EndIf
      
      xx + 1
      a - dy
      If a <= 0
         a + dx
         yy + addval
      EndIf
   Wend
   
EndProcedure

;-------------------------------------------

Procedure Liniego(x.i, y.i, xx.i, yy.i, color.l, move.i, shift.u, lr.i)
  
  For i=0 To move
  shift = (shift << 1) | ((shift >> 15) & $7fff)  
  Next i

  Linie(x, y, xx, yy, shift, color, lr)     

EndProcedure

;-------------------------------------------

Procedure Boxgo(x.i, y.i, xx.i, yy.i, color.l, move.i, shift.u, lr.i)

  xx - 1 : yy - 1
  
 If lr
   Liniego(x, y, x + xx, y, color, move, shift, 1)
   Liniego(x + xx, y, x + xx, y + yy, color, move, shift, 1)
   Liniego(x, y + yy, x + xx, y + yy, color, move, shift, 0)
   Liniego(x, y + yy, x, y, color, move, shift, 0)
  Else
   Liniego(x, y, x + xx, y, color, move, shift, 0)
   Liniego(x + xx, y, x + xx, y + yy, color, move, shift, 0)
   Liniego(x, y + yy, x + xx, y + yy, color, move, shift, 1)
   Liniego(x, y + yy, x, y, color, move, shift, 1)
 EndIf
   
EndProcedure

; --------Loop-----------------------------

ExamineDesktops()

If OpenWindow (0, DesktopWidth(0) / 2 - 200, DesktopHeight(0) / 2 - 250, 500, 250, "")
   
   CanvasGadget(0, 0, 0, 500 , 400)
   AddWindowTimer(0, 0, 40)
   
   xx=3 : yy=2

   Repeat
      Select WaitWindowEvent()
         Case #PB_Event_CloseWindow:
            Break
         
          Case #PB_Event_Timer
                    
           x+xx : If x>491 : xx=-3 : EndIf
                  If x<3   : xx=3  : EndIf

           y+yy : If y>241 : yy=-3 : EndIf
                  If y<3   : yy=3  : EndIf
            
              If StartDrawing(CanvasOutput(0))
                  Box   (0, 0, 500, 250, $FFFFFF)
                  DrawingMode(#PB_2DDrawing_Outlined) ; Zeichnen von Flächen erfolgt nicht ausgefüllt
                  
                  Box (184, 104, 132, 32, $FF)
                  Box (185, 105, 130, 30, $FF)
                  Box (186, 106, 128, 28, $FF)
                  
                 If swapp<50
                  Boxgo (184, 104, 132, 32, $FFFF00, move, %0011110000111100,1)
                  Boxgo (185, 105, 130, 30, $FFFF00, move, %0011110000111100,1)
                  Boxgo (186, 106,  128, 28,$FFFF00, move, %0011110000111100,1)
                   Else
                  Boxgo (184, 104, 132, 32, $00FFFF, move, %0011110000111100,0)
                  Boxgo (185, 105, 130, 30, $00FFFF, move, %0011110000111100,0)
                  Boxgo (186, 106,  128, 28,$00FFFF, move, %0011110000111100,0)
                 EndIf
                
                  Boxgo (174, 94, 152, 52, $FF0000, move, %0010001111000100,0)
                  Boxgo (175, 95, 150, 50, $FF0000, move, %0010001111000100,0)
                  Boxgo (176, 96, 148, 48, $FF0000, move, %0010001111000100,0)
                  
                  Boxgo (164, 84, 172, 72, $FF, move, %0010011111100100,1)
                  Boxgo (165, 85, 170, 70, $FF, move, %0010011111100100,0)
                  Boxgo (166, 86, 168, 68, $FF, move, %0010011111100100,1)
                  
                  Boxgo (154, 74, 192, 92, $FF, move, %1001111111110001,0)
                  Boxgo (155, 75, 190, 90, $FF, move, %0011001111001100,1)
                  Boxgo (156, 76, 188, 88, $FF, move, %1111110000111111,0)
                  
                  Boxgo (148, 68, 204, 104, $0 , move, %1101101101101101,1)
                  Boxgo (144, 64, 212, 112, $0 , move, %0011111111111111,0)
                  Boxgo (140, 60, 220, 120, $0 , move, %0011001111111111,1)

                  Boxgo (144, 50, 212, 2, $32CD32 , move, %0011110011110011,0)
                  Boxgo (143, 49, 214, 4, $32CD32 , move, %0011001111110011,1)
                  Boxgo (142, 48, 216, 6, $32CD32 , move, %0011110011110011,0)
                  
                  Boxgo (2+x, 2+y, 4, 4, $32CD32 , move, %0011111111100111,1)
                  Boxgo (1+x, 1+y, 6, 6, $32CD32 , move, %0011111111100111,0)
                  Boxgo (0+x, 0+y, 8, 8, $32CD32 , move, %0011111111100111,1)
                  
                  liniego(144,40,250,10,$FF, move,%0011111111100111, 1)
                  liniego(144,40,250,11,$FF, move,%0011111111100111, 1)
                  liniego(144,40,250,12,$FF, move,%0011111111100111, 1)
                  liniego(250,10,356,40,$FF, move,%0011111111100111, 0)
                  liniego(250,11,356,40,$FF, move,%0011111111100111, 0)
                  liniego(250,12,356,40,$FF, move,%0011111111100111, 0)

                StopDrawing()
              EndIf
              
                   move +1 ; Animations Counter für bewegte Linien
                   If move >15 : move = 0 : EndIf
                   
                   swapp +1 ; Animations Counter für bewegte Linien
                   If swapp>100 : swapp= 0 : EndIf
                    
      EndSelect
      
   ForEver
   
EndIf
Here a rotate 32 Bit version

Code: Select all

Procedure Linie(x.i, y.i, xx.i, yy.i, shift.q, color.l, lr.i)
   
  ; Achtung Plot unterstützt kein Clipping
  
  ; Idee und coding - Werner Albus - www.nachtoptik.de
  ; Linien Algorithmus übernommen aus einem Sample von Udo Kessler
   
   Protected a.i, dx.i, dy.i, addval.i = 1
   Protected *plotX.Integer = @xx, *plotY.Integer = @yy
   
   If Abs(x - xx) <= Abs(y - yy) ; Winkel größer 45°
      Swap x, y
      Swap xx, yy
      *plotX = @yy
      *plotY = @xx
   EndIf
      
   If x < xx
      Swap x, xx
      Swap y, yy
   EndIf
   
   If y < yy
      y = 2 * yy - y
      addval = -1
   EndIf
   
   dy = 2 * (y - yy)
   a  = x - xx
   dx = 2 * a
   
   While xx <= x
      
      If shift & 1
         Plot(*plotX\i, *plotY\i, color)
      EndIf
      
      If lr
         shift = (shift << 1) | ((shift >> 31) & $7fffffff)
      Else
         shift = ((shift >> 1) & $7fffffff) | (shift << 31)
      EndIf
      
      xx + 1
      a - dy
      If a <= 0
         a + dx
         yy + addval
      EndIf
   Wend
   
EndProcedure

;-------------------------------------------

Procedure Liniego(x.i, y.i, xx.i, yy.i, color.l, move.i, shift.q, lr.i)
  
  For i=0 To move
  shift = (shift << 1) | ((shift >> 31) & $7fffffff)  
  Next i

  Linie(x, y, xx, yy, shift, color, lr)     

EndProcedure

;-------------------------------------------

Procedure Boxgo(x.i, y.i, xx.i, yy.i, color.l, move.i, shift.q, lr.i)

  xx - 1 : yy - 1
  
 If lr
   Liniego(x, y, x + xx, y, color, move, shift, 1)
   Liniego(x + xx, y, x + xx, y + yy, color, move, shift, 1)
   Liniego(x, y + yy, x + xx, y + yy, color, move, shift, 0)
   Liniego(x, y + yy, x, y, color, move, shift, 0)
  Else
   Liniego(x, y, x + xx, y, color, move, shift, 0)
   Liniego(x + xx, y, x + xx, y + yy, color, move, shift, 0)
   Liniego(x, y + yy, x + xx, y + yy, color, move, shift, 1)
   Liniego(x, y + yy, x, y, color, move, shift, 1)
 EndIf
   
EndProcedure

; --------Loop-----------------------------

ExamineDesktops()

If OpenWindow (0, DesktopWidth(0) / 2 - 200, DesktopHeight(0) / 2 - 250, 500, 250, "")
   
   CanvasGadget(0, 0, 0, 500 , 400)
   AddWindowTimer(0, 0, 40)
   
   xx=3 : yy=2

   Repeat
      Select WaitWindowEvent()
         Case #PB_Event_CloseWindow:
            Break
         
          Case #PB_Event_Timer
                    
           x+xx : If x>491 : xx=-3 : EndIf
                  If x<3   : xx=3  : EndIf

           y+yy : If y>241 : yy=-3 : EndIf
                  If y<3   : yy=3  : EndIf
            
              If StartDrawing(CanvasOutput(0))
                  Box   (0, 0, 500, 250, $FFFFFF)
                  DrawingMode(#PB_2DDrawing_Outlined) ; Zeichnen von Flächen erfolgt nicht ausgefüllt
                  
                  Box (184, 104, 132, 32, $FF)
                  Box (185, 105, 130, 30, $FF)
                  Box (186, 106, 128, 28, $FF)
                  
                 If swapp<50
                  Boxgo (184, 104, 132, 32, $FFFF00, move, %00111100001111000011110000111100,1)
                  Boxgo (185, 105, 130, 30, $FFFF00, move, %00111100001111000011110000111100,1)
                  Boxgo (186, 106,  128, 28,$FFFF00, move, %00111100001111000011110000111100,1)
                   Else
                  Boxgo (184, 104, 132, 32, $00FFFF, move, %00111100001111000011110000111100,0)
                  Boxgo (185, 105, 130, 30, $00FFFF, move, %00111100001111000011110000111100,0)
                  Boxgo (186, 106,  128, 28,$00FFFF, move, %00111100001111000011110000111100,0)
                 EndIf
                
                  Boxgo (174, 94, 152, 52, $FF0000, move, %00100011110001000011110000111100,0)
                  Boxgo (175, 95, 150, 50, $FF0000, move, %00100011110001000011110000111100,0)
                  Boxgo (176, 96, 148, 48, $FF0000, move, %00100011110001000011110000111100,0)
                  
                  Boxgo (164, 84, 172, 72, $FF, move, %00100111111001000011110000111100,1)
                  Boxgo (165, 85, 170, 70, $FF, move, %00100111111001000011110000111100,0)
                  Boxgo (166, 86, 168, 68, $FF, move, %00100111111001000011110000111100,1)
                  
                  Boxgo (154, 74, 192, 92, $FF, move, %10011111111100010011110000111100,0)
                  Boxgo (155, 75, 190, 90, $FF, move, %00110011110011000011110000111100,1)
                  Boxgo (156, 76, 188, 88, $FF, move, %11111100001111110011110000111100,0)
                  
                  Boxgo (148, 68, 204, 104, $0 , move, %11011011011011010011110000111100,1)
                  Boxgo (144, 64, 212, 112, $0 , move, %00111111111111110011110000111100,0)
                  Boxgo (140, 60, 220, 120, $0 , move, %00110011111111110011110000111100,1)

                  Boxgo (144, 50, 212, 2, $32CD32 , move, %00111100111100110011110000111100,0)
                  Boxgo (143, 49, 214, 4, $32CD32 , move, %00110011111100110011110000111100,1)
                  Boxgo (142, 48, 216, 6, $32CD32 , move, %00111100111100110011110000111100,0)
                  
                  Boxgo (2+x, 2+y, 4, 4, $32CD32 , move, %00111111111001110011110000111100,1)
                  Boxgo (1+x, 1+y, 6, 6, $32CD32 , move, %00111111111001110011110000111100,0)
                  Boxgo (0+x, 0+y, 8, 8, $32CD32 , move, %00111111111001110011110000111100,1)
                  
                  liniego(144,40,250,10,$FF, move,%00111111111001110011110000111100, 1)
                  liniego(144,40,250,11,$FF, move,%00111111111001110011110000111100, 0)
                  liniego(144,40,250,12,$FF, move,%00111111111001110011110000111100, 1)
                  liniego(250,10,356,40,$FF, move,%00111111111001110011110000111100, 0)
                  liniego(250,11,356,40,$FF, move,%00111111111001110011110000111100, 1)
                  liniego(250,12,356,40,$FF, move,%00111111111001110011110000111100, 0)

                StopDrawing()
              EndIf
              
                   move +1 ; Animations Counter für bewegte Linien
                   If move >31 : move = 0 : EndIf
                   
                   swapp +1 ; Animations Counter für bewegte Linien
                   If swapp>100 : swapp= 0 : EndIf
                    
      EndSelect
      
   ForEver
   
EndIf