Sweep second clock in newLISP

Guiserver, GTK-server, OpenGL, PostScript,
HTML 5, MIDI, IDE
Locked
steloflute
Posts: 13
Joined: Tue Nov 06, 2012 4:02 pm
Contact:

Sweep second clock in newLISP

Post by steloflute »

Hello,

I have made a clock program in newLISP.

http://steloflute.tistory.com/entry/newLISP-SweepSecond

How do you remove flickering?

cormullion
Posts: 2038
Joined: Tue Nov 29, 2005 8:28 pm
Location: latiitude 50N longitude 3W
Contact:

Re: Sweep second clock in newLISP

Post by cormullion »

You may be doing too much work in each update loop. I have a half-finished newLISP clock, which has many problems of style and elegance, and uses too much code repetition and global scoping, but at least it doesn't exhibit any flickering... :)

Code: Select all

#!/usr/bin/env newlisp

(load "/usr/share/newlisp/guiserver.lsp")

(constant 'PI 3.141592653589793)
(define (rad->deg r) (mul r (div 180 PI)))
(define (deg->rad d) (mul d (div PI 180)))
(define (sind _e) (sin (deg->rad (eval _e))))
(define (cosd _e) (cos (deg->rad (eval _e))))  

(set 'frame-width 500)
(set 'dial-width 440 
     'minute-hand-length  (+ (/ dial-width 2) 20)
     'minutehand-width 3)
     
(gs:init)
(gs:frame 'F 50 50 550 550 "Clock") 
(gs:set-background 'F gs:black)
(gs:canvas 'C)
(gs:set-size 'C frame-width frame-width)
(gs:set-font 'C "Helvetica-Bold" 26)
(gs:set-resizable 'F true)
(gs:add-to 'F 'C)

; dial 
(gs:set-canvas 'C)
(gs:fill-circle 'dial 0 0 (/ frame-width 2) '(.6 .8 .7 1))
(gs:draw-circle 'dial 0 0 (/ frame-width 2) '(.2 .2 .2 1))

(gs:set-paint  '(.5 0 .5 1))
(for (i 1 12)
   (set 'x (int 
     (sub (mul (cosd (sub (mul i 30) 90)) (- (/ frame-width 2) 20)) 5)))
   (set 'y (int 
     (add (mul (sind (sub (mul i 30) 90)) (- (/ frame-width 2) 20)) 5)))
   (gs:draw-text (string "12" i) (string i) x y))

; hands 
(gs:set-translation (/ frame-width 2) (/ frame-width 2))
(gs:fill-rect  'hourhand -3 -5 (* minutehand-width 3) (- minute-hand-length 70))
(gs:rotate-tag 'hourhand 180 0 0)

(gs:fill-rect  'minutehand -1 -15 minutehand-width minute-hand-length)
(gs:rotate-tag 'minutehand 180 0 0)

(gs:set-paint '(1 0 0))
(gs:fill-rect  'secondhand -1 -15 minutehand-width minute-hand-length)
(gs:rotate-tag 'secondhand 180 0 0)

(define (ms->list n)
  ; convert milliseconds to hour min sec list
  (let ((factors '(1000 60 60))
        (result '()))
    (map (fn (f) (push (mod n f) result) (set 'n (/ n f))) factors)
	(push n result)
  result))

(define (hour-to-angle h m)
   (mod (mul (div (add h (div m 60)) 12) 360) 360))

(define (minute-to-angle m s)
   (mod (mul (div (add m (div s 60)) 60) 360) 360))

(define (second-to-angle s ms)
   (mod (mul (div (add s (div ms 1000)) 60) 360) 360))

(define (init)
   (map set '(hour minute second millisecond) (ms->list (time-of-day)))
   (set 'hour-hand-rotation     (hour-to-angle hour minute))
   (set 'minute-hand-rotation   (minute-to-angle minute second))
   (set 'second-hand-rotation   (second-to-angle second millisecond))  
   (gs:rotate-tag 'hourhand     hour-hand-rotation  0 0)
   (gs:rotate-tag 'minutehand   minute-hand-rotation 0 0)
   (gs:rotate-tag 'secondhand   second-hand-rotation 0 0))
  
(define (update)
   (gs:set-translation (/ frame-width 2) (/ frame-width 2))
   (map set '(hour minute second millisecond) (ms->list (time-of-day))) 
   ; new angles:
   (set 'hour-hand-angle        (hour-to-angle hour minute))
   (set 'minute-hand-angle      (minute-to-angle minute second))
   (set 'second-hand-angle      (second-to-angle second millisecond))
   ; find delta
   (set 'hour-hand-delta        (sub hour-hand-angle hour-hand-rotation)
        'minute-hand-delta      (sub minute-hand-angle minute-hand-rotation)
        'second-hand-delta      (sub second-hand-angle second-hand-rotation))
   (gs:rotate-tag 'hourhand     hour-hand-delta   0 0)
   (gs:rotate-tag 'minutehand   minute-hand-delta 0 0)
   (gs:rotate-tag 'secondhand   second-hand-delta 0 0) 
   ; remember new position
   (set 'hour-hand-rotation     (mod (add hour-hand-rotation hour-hand-delta) 360)) 
   (set 'minute-hand-rotation   (mod (add minute-hand-rotation minute-hand-delta) 360))  
   (set 'second-hand-rotation   (mod (add second-hand-rotation second-hand-delta) 360))  
   )
   
(gs:set-visible 'F true) 
(init)
(while (gs:check-event 5000)  
   (update)
   (sleep 50))

Locked