[plt-scheme] Slow graphics on NetBSD

From: Yasir Malik (ymalik at cs.stevens-tech.edu)
Date: Fri Jul 11 15:30:11 EDT 2003

Thank you for replying.  This is just a simple program I had to write for
one one of my classes.  Again, this program runs very fast under Windows;
under NetBSD, the fly moves probably once every half a second.  And I
don't think it's a problem with the way I've configured my graphics card:
this program runs just as slow on all (well, the ones I've checked) the
machines in our CS Lab running NetBSD.
Yasir

;Just click execute.  Program execution stops when 'Done' is displayed at
the command prompt.
;The LEFT BUTTON is used to place red points onto the screen.  Once the
;RIGHT BUTTON is clicked, the program starts running and user cannot
select anymore points.
;If the user is lazy and wants to generate random points, he can click the
MIDDLE BUTTON to generate random points.
;The user still has the chance to select other points with the mouse.
;If the user wants to generate more random points at a time, change the
'numrand' value on line 20.

;Change only the values above line 30.  Changing anything is optional.

(require (lib "graphics.ss" "graphics"))

(open-graphics)


;the height of each pixel; don't make the pixhght value to high or else
DrScheme will complain
;since the viewport will be too large
(define pixhght 3)

;the number of random pixels
(define numrand 1000)

;the dimensions of the world with each pixel being pixhght wide and high
;if you want a world that is 1000x1000 pixels, enter a value for xmax and
ymax
;such that 1000 = pixhght*({xmax,ymax}+1)
(define xmax 200)
(define ymax 200)



;change nothing past this line



(define red (make-rgb 1.0 0.0 0.0))
(define white (make-rgb 1.0 1.0 1.0))

;the dimensions of the viewport
(define sxmax (* pixhght (+ xmax 1)))
(define symax (* pixhght (+ ymax 1)))

(define v (open-viewport "Fly"  sxmax symax))

;this draws a big pixel of height and width pixhght
(define (draw-big-pixel x y color)
  ((draw-solid-rectangle v) (make-posn (* pixhght x) (* pixhght y))
pixhght pixhght color)
)

(define-struct fly (x y theta))

;this generates 'n' random red points; the user can enter his own points
;if he wants
(define (generate n)
  (cond
    [(= n 0) (display "Drew random points\n")]
    [else (begin
            (draw-big-pixel (random (+ xmax 1)) (random (+ ymax 1)) red)
            (generate (- n 1)))]
  )
)

;determines whether a pixel is white
(define (is-white? x y)
  (= ((get-pixel v) (make-posn (* x pixhght) (* y pixhght))) 0)
)

;explanation of the fly:  the fly has a head, and whenever it turns, its
head turns in the direction
;the fly goes.  To indicate the fly's head orientation, I gave it a theta
value that corresponds
;to the angle the fly's head is pointing towards.  The initial orientation
is 90 degrees
(define (go!)
  (define (aux f)
    (cond
      ;the fly has reached past the border, so stop
      [(or (> (fly-x f) xmax) (< (fly-x f) 0) (> (fly-y f) ymax) (< (fly-y
f) 0)) (display "Done")]

      ;the fly is on a white pixel, so move left, and invert the previous
pixel
      [(is-white? (fly-x f) (fly-y f)) (begin
                         (draw-big-pixel (fly-x f) (fly-y f) red)
                         (let*(
                               (newf (get-new-pos-l f))
                              )
                           (aux newf)
                         )
                       )
      ]

      ;the fly is on a red pixel, so move right, and invert the previous
pixel
      [else (begin
              (draw-big-pixel (fly-x f) (fly-y f) white)
              (let*(
                    (newf (get-new-pos-r f))
                    )
                (aux newf)
                )
             )
      ]
    )
  )(aux (make-fly (quotient xmax 2) (quotient ymax 2) 90))
)

;function that moves a fly on a white square to the left
;i didn't use any tricks or special formulas--just my sense of spatial
relationships
;i mod the theta value because the value might go past 360, but in that
case, it's
;equivalent to the other theta values between 0 and 360
(define (get-new-pos-l f)
  (cond
    [(= (modulo (fly-theta f) 360) 0) (make-fly (fly-x f) (- (fly-y f) 1)
(+ (fly-theta f) 90))]
    [(= (modulo (fly-theta f) 360) 90) (make-fly (- (fly-x f) 1) (fly-y f)
(+ (fly-theta f) 90))]
    [(= (modulo (fly-theta f) 360) 180) (make-fly (fly-x f) (+ (fly-y f)
1) (+ (fly-theta f) 90))]
    [else (make-fly (+ (fly-x f) 1) (fly-y f) (+ (fly-theta f) 90))]
  )
)

;function that moves a fly on a red square to the right
(define (get-new-pos-r f)
  (cond
    [(= (modulo (fly-theta f) 360) 0) (make-fly (fly-x f) (+ (fly-y f) 1)
(- (fly-theta f) 90))]
    [(= (modulo (fly-theta f) 360) 90) (make-fly (+ (fly-x f) 1) (fly-y f)
(- (fly-theta f) 90))]
    [(= (modulo (fly-theta f) 360) 180) (make-fly (fly-x f) (- (fly-y f)
1) (- (fly-theta f) 90))]
    [else (make-fly (- (fly-x f) 1) (fly-y f) (- (fly-theta f) 90))]
  )
)

((draw-solid-rectangle v) (make-posn 0 0) sxmax symax white)
(draw-big-pixel (quotient xmax 2) (quotient ymax 2) red)

;function that controls the mouse events
(define (mouse-func)
  (define (aux mouse)
    (cond
      [(right-mouse-click? mouse) (display "Done selecting\nGo!\n")]
      [(left-mouse-click? mouse) (begin (let* (
                                               (p (mouse-click-posn
mouse))
                                               (px (posn-x p))
                                               (py (posn-y p))
                                               )
                                          (draw-big-pixel (/ (- px (modulo
px pixhght)) pixhght)
                                                          (/ (- py (modulo
py pixhght)) pixhght)
                                                          red)
                                          )
                                        (aux (get-mouse-click v)))
      ]
      [(middle-mouse-click? mouse) (begin (generate numrand) (aux
(get-mouse-click v)))]
      [else (aux (get-mouse-click v))]
    )
  )(aux (get-mouse-click v))
)

(mouse-func)
(go!)


Posted on the users mailing list.