(DEFINE-FILE-INFO READTABLE "XCL" PACKAGE "PLOT")(il:filecreated " 1-Dec-88 12:04:21" il:{qv}<idl>next>plot-objects.\;24 70027        il:|changes| il:|to:|  (il:functions define-plot-object symbol-to-bitmap l1-metric l1-metric-xy                                    sine-wave plot-points get-compound draw-graph)      il:|previous| il:|date:| "15-Nov-88 18:51:12" il:{qv}<idl>next>plot-objects.\;22); Copyright (c) 1988 by Xerox Corporation.  All rights reserved.(il:prettycomprint il:plot-objectscoms)(il:rpaqq il:plot-objectscoms          (           (il:* il:|;;| "Definer for plot-objects")           (il:coms (il:variables *plot-object-types* *plot-object-type-table*                            *plot-object-constructor-table* *plot-object-menus*)                  (il:functions define-plot-object)                  (il:functions type-of-object))                      (il:* il:|;;| "Utilities")           (il:coms                   (il:* il:|;;| "Bitmaps")                  (il:variables *star* *circle* *cross*)                  (il:functions bitmap-to-symbol symbol-to-bitmap)                  (il:functions make-symbol-menu)                                    (il:* il:|;;| "Line styles")                  (il:variables *dash* *dot* *dot-dash*)                  (il:functions make-dashing-menu)                                    (il:* il:|;;| "Textures")                  (il:variables *shade-1* *shade-2* *shade-3* *shade-4* *shade-5* *shade-6* *shade-7*                         *shade-8*)                  (il:functions make-texture-menu)                                    (il:* il:|;;| "Line styles")                  (il:structures line-style)                  (il:functions change-style-width change-style-dashing)                                    (il:* il:|;;| "Generic labeling")                  (il:functions label-generic)                                    (il:* il:|;;| "Distance utilities")                  (il:functions l1-metric l1-metric-xy positions-list-extent positions-list-distance                         no-extent)                                    (il:* il:|;;| "Rendering Utilities")                  (il:functions connect-positions)                                    (il:* il:|;;| "Debugging")                  (il:functions sine-wave plot-object-error))                      (il:* il:|;;| "Points")           (il:coms (il:structures point)                  (il:functions make-point)                  (il:functions draw-point erase-point highlight-point extent-of-point                          distance-to-point label-point move-point copy-point put-point get-point)                  (il:functions plot-point plot-points change-point-symbol))                      (il:* il:|;;| "Curves")           (il:coms (il:structures curve)                  (il:functions make-curve)                  (il:functions draw-curve erase-curve highlight-curve extent-of-curve                          distance-to-curve move-curve copy-curve put-curve get-curve)                  (il:functions plot-curve change-curve-width change-curve-dashing))                      (il:* il:|;;| "Polygons")           (il:coms (il:structures polygon)                  (il:functions make-polygon)                  (il:functions draw-polygon erase-polygon highlight-polygon extent-of-polygon                          distance-to-polygon move-polygon copy-polygon put-polygon get-polygon)                  (il:functions plot-polygon change-polygon-width change-polygon-dashing))                      (il:* il:|;;| "Filled rectangles")           (il:coms (il:structures rectangle)                  (il:functions rectangle-right rectangle-stream-right rectangle-top                          rectangle-stream-top)                  (il:functions make-rectangle)                  (il:functions draw-rectangle erase-rectangle highlight-rectangle                          extent-of-rectangle distance-to-rectangle move-rectangle copy-rectangle                          put-rectangle get-rectangle)                  (il:functions plot-rectangle change-rectangle-border change-rectangle-texture))                      (il:* il:|;;| "Text")           (il:coms (il:structures text)                  (il:functions make-text)                  (il:functions draw-text erase-text highlight-text extent-of-text distance-to-text                          move-text copy-text put-text get-text)                  (il:functions plot-text))                      (il:* il:|;;| "Compound objects")           (il:coms (il:structures compound)                  (il:functions make-compound)                  (il:functions draw-compound erase-compound highlight-compound extent-of-compound                          distance-to-compound move-compound copy-compound put-compound get-compound)                  (il:functions plot-compound))                      (il:* il:|;;| "Analytic lines")           (il:coms (il:structures line)                  (il:functions make-line)                  (il:functions draw-analytic-line erase-analytic-line highlight-line                          distance-to-line copy-line extent-of-line put-line get-line)                  (il:functions plot-line change-line-width change-line-dashing))                      (il:* il:|;;| "Graphs")           (il:coms (il:structures graph)                  (il:functions make-graph)                  (il:functions draw-graph erase-graph highlight-graph distance-to-graph copy-graph                          extent-of-graph)                  (il:functions plot-graph change-graph-width change-graph-dashing))           (xcl:file-environments "PLOT-OBJECTS")))(il:* il:|;;| "Definer for plot-objects")(defvar *plot-object-types* nil)(defvar *plot-object-type-table* (make-hash-table :test #'eq))(defvar *plot-object-constructor-table* (make-hash-table :test #'eq))(defvar *plot-object-menus* (make-hash-table :test #'eq))(xcl:defdefiner define-plot-object il:structures (type &key methods instance-vars menu-items)   (let* ((type-package (symbol-package type))          (type-string (string type))          (type-keyword (intern type-string (find-package "KEYWORD")))          (stucture-name (intern (concatenate 'string type-string "-PLOT-OBJECT")                                type-package))          (conc-name (concatenate 'string type-string "-"))          (constructor (intern (concatenate 'string "%MAKE-" type-string)                              type-package))          (copier (intern (concatenate 'string "%COPY-" type-string)                         type-package))          (methods-name (intern (concatenate 'string "*" type-string "-OBJECT-METHODS*")                               type-package))          (methods-alist '((:draw-fn . "DRAW-")                           (:erase-fn . "ERASE-")                           (:highlight-fn . "HIGHLIGHT-")                           (:lowlight-fn . "HIGHLIGHT-")                           (:extent-fn . "EXTENT-OF-")                           (:distance-fn . "DISTANCE-TO-")                           (:label-fn . "LABEL-")                           (:move-fn . "MOVE-")                           (:copy-fn . "COPY-")                           (:put-fn . "PUT-")                           (:get-fn . "GET-"))))         (setq methods               (mapcan #'(lambda (pair)                                (let* ((keyword (car pair))                                       (prefix (cdr pair))                                       (supplied (cdr (pt:memq keyword methods))))                                      (if supplied                                          (let ((value (car supplied)))                                               (if value                                                   `(,keyword ',value)))                                          `(,keyword ',(intern (concatenate 'string prefix                                                                       type-string)                                                              type-package)))))                      methods-alist))         `(progn (defparameter ,methods-name (make-plot-methods ,@methods))                 (defstruct (,stucture-name (:include plot-object (methods ,methods-name))                                   (:conc-name ,conc-name)                                   (:constructor ,constructor)                                   (:copier ,copier))                    ,@instance-vars)                 (pushnew ',type-keyword *plot-object-types*)                 (setf (gethash ',stucture-name *plot-object-type-table*)                       ',type-keyword)                 (setf (gethash ',type-keyword *plot-object-constructor-table*)                       ',constructor)                 ,@(if menu-items                       `((setf (gethash ',type-keyword *plot-object-menus*)                               (make-menu :items (append (menu-items *default-middle-menu*)                                                        ',menu-items)                                      :when-selected-fn                                      'default-when-selected-fn :track-cursor-p t)))))))(defun type-of-object (plot-object)   (gethash (type-of plot-object)          *plot-object-type-table*))(il:* il:|;;| "Utilities")(il:* il:|;;| "Bitmaps")(defvar *star* '#*(5 5)JH@@G@@@OH@@G@@@JH@@)(defvar *circle* '#*(5 5)G@@@HH@@HH@@HH@@G@@@)(defvar *cross* '#*(5 5)B@@@B@@@OH@@B@@@B@@@)(defun bitmap-to-symbol (bitmap)   (let ((sym-tail (member bitmap '(*star* *circle* *cross*)                          :key                          'symbol-value)))        (if sym-tail            (car sym-tail)            bitmap)))(defun symbol-to-bitmap (symbol)   (let ((sym-tail (pt:memq symbol '(*star* *circle* *cross*))))        (if sym-tail            (symbol-value (car sym-tail))            symbol)))(defun make-symbol-menu ()   (flet ((bitmap-icon (bitmap &optional (scale-factor 2))                 (let* ((width (bitmap-width bitmap))                        (height (bitmap-height bitmap))                        (icon (make-bitmap (* scale-factor width)                                     (* scale-factor height))))                       (stream-bitblt bitmap icon :destination-left (truncate (- (bitmap-width icon)                                                                                 width)                                                                           2)                              :destination-bottom                              (truncate (- (bitmap-height icon)                                           height)                                     2))                       icon)))         (make-menu :items `((,(bitmap-icon *star* 4)                              *star*)                             (,(bitmap-icon *circle* 4)                              *circle*)                             (,(bitmap-icon *cross* 4)                              *cross*))                :border-size 1 :track-cursor-p t)))(il:* il:|;;| "Line styles")(defvar *dash* '(5))(defvar *dot* '(1 5))(defvar *dot-dash* '(5 5 1 5))(defun make-dashing-menu ()   (flet ((fill-bitmap-with-dashing (dashing &optional (width 50)                                           (height 10)                                           (thickness 2))                 (let* ((bitmap (make-bitmap width height))                        (stream (il:dspcreate bitmap))                        (y (truncate height 2)))                       (stream-draw-line 0 y width y stream :width thickness :operation boole-1                               :dashing dashing)                       bitmap)))         (make-menu :items `((,(fill-bitmap-with-dashing nil)                              :solid)                             (,(fill-bitmap-with-dashing *dash*)                              *dash*)                             (,(fill-bitmap-with-dashing *dot*)                              *dot*)                             (,(fill-bitmap-with-dashing *dot-dash*)                              *dot-dash*))                :border-size 1 :track-cursor-p t)))(il:* il:|;;| "Textures")(defvar *shade-1* 64)(defvar *shade-2* 576)(defvar *shade-3* 4680)(defvar *shade-4* 37449)(defvar *shade-5* 55899)(defvar *shade-6* 31710)(defvar *shade-7* 64479)(defvar *shade-8* 65023)(defun make-texture-menu ()   (flet ((texture-bitmap (texture &optional (width 30)                                 (height 20))                 (let* ((bitmap (make-bitmap width height)))                       (stream-bltshade texture bitmap)                       bitmap)))         (make-menu :items `((,(texture-bitmap *shade-1*)                              *shade-1*)                             (,(texture-bitmap *shade-2*)                              *shade-2*)                             (,(texture-bitmap *shade-3*)                              *shade-3*)                             (,(texture-bitmap *shade-4*)                              *shade-4*)                             (,(texture-bitmap *shade-5*)                              *shade-5*)                             (,(texture-bitmap *shade-6*)                              *shade-6*)                             (,(texture-bitmap *shade-7*)                              *shade-7*)                             (,(texture-bitmap *shade-8*)                              *shade-8*))                :border-size 1 :track-cursor-p t)))(il:* il:|;;| "Line styles")(defstruct (line-style (:type list)                           (:conc-name "STYLE-"))   (width 1)   dashing color)(defun change-style-width (new-width style plot-object plot)   (il:* il:|;;| "Assumes an open plot-window")   (when (null new-width)       (print-plot-prompt "Indicate new width" plot)       (setq new-width (il:rnumber nil nil nil nil t nil t))       (print-plot-prompt "" plot))   (when new-width       (let ((view-port (plot-view-port plot)))            (erase-plot-object plot-object view-port plot)            (setf (style-width style)                  new-width)            (draw-plot-object plot-object view-port plot))))(defun change-style-dashing (new-dashing style plot-object plot)   (il:* il:|;;| "Assumes an open plot-window")   (when (null new-dashing)       (print-plot-prompt "Indicate new dashing" plot)       (setq new-dashing (pop-up-menu (il:constant (make-dashing-menu))))       (print-plot-prompt "" plot))   (when new-dashing       (let ((view-port (plot-view-port plot)))            (erase-plot-object plot-object view-port plot)            (setf (style-dashing style)                  (if (eq new-dashing :solid)                      nil                      new-dashing))            (draw-plot-object plot-object view-port plot))))(il:* il:|;;| "Generic labeling")(defun label-generic (object plot)              (il:* il:\; "Edited  5-May-87 17:56 by jop")   (il:* il:|;;| "Generic label routine.  Intended for interactive use only")   (let ((view-port (plot-view-port plot))         (text-object (plot-object-prop object :label-object)))        (if text-object            (draw-plot-object text-object view-port plot)            (let ((label (plot-object-label object))                  (label-position (progn (print-plot-prompt "Select a position for label: " plot)                                         (stream-to-world (get-position (plot-window plot))                                                view-port))))                 (setq text-object (make-text label-position label :font *small-plot-font*))                 (draw-plot-object text-object view-port plot)                 (setf (plot-object-prop object :label-object)                       text-object)))))(il:* il:|;;| "Distance utilities")(defmacro l1-metric (position-1 position-2)   (pt:once-only (position-1 position-2)          `(+ (abs (- (position-x ,position-1)                      (position-x ,position-2)))              (abs (- (position-y ,position-1)                      (position-y ,position-2))))))(defmacro l1-metric-xy (position-1 x y)   (pt:once-only (position-1)          `(+ (abs (- (position-x ,position-1)                      ,x))              (abs (- (position-y ,position-1)                      ,y)))))(defun positions-list-extent (positions)   (let* ((first-position (car positions))          (min-x (position-x first-position))          (max-x min-x)          (min-y (position-y first-position))          (max-y min-y))         (dolist (position (cdr positions))             (let ((x (position-x position))                   (y (position-y position)))                  (if (< x min-x)                      (setq min-x x)                      (if (> x max-x)                          (setq max-x x)))                  (if (< y min-y)                      (setq min-y y)                      (if (> y max-y)                          (setq max-y y)))))         (make-extent :min-x min-x :max-x max-x :min-y min-y :max-y max-y)))(defun positions-list-distance (positions target)   (let ((min (l1-metric (car positions)                     target)))        (dolist (position (cdr positions))            (let ((candidate (l1-metric position target)))                 (if (< candidate min)                     (setq min candidate))))        min))(defun no-extent (plot-object)   (declare (ignore plot-object))   nil)(il:* il:|;;| "Rendering Utilities")(defun connect-positions (stream-positions stream stream-subregion operation line-width color                                     dashing &optional close-loop-p)   (let ((first-position (car stream-positions))         (rest-positions (cdr stream-positions)))        (stream-move-to (position-x first-position)               (position-y first-position)               stream)        (dolist (position rest-positions)            (clipped-draw-to (position-x position)                   (position-y position)                   stream stream-subregion :width line-width :operation operation :color color                    :dashing dashing))        (if close-loop-p            (clipped-draw-to (position-x first-position)                   (position-y first-position)                   stream stream-subregion :width line-width :operation operation :color color                    :dashing dashing))))(il:* il:|;;| "Debugging")(defun sine-wave (n from to &optional (frequency 1)                        (amplitude 1))   (il:* il:|;;| "produce N points on a sine wave")   (let* ((twopi (* 2.0 pi))          (range (- to from))          (x from)          (inc (/ (float range)                  n)))         (pt:with-collection (dotimes (i n)                                 (pt:collect (make-position x (* amplitude (sin (* frequency x)))))                                 (incf x inc)))))(defun plot-object-error (&rest args)   (error "Unimplemented method"))(il:* il:|;;| "Points")(define-plot-object point :instance-vars (position stream-position symbol)   :menu-items (("Symbol" change-point-symbol "Change point symbol")))(defun make-point (position &key (symbol *star*)                             label menu)   (%make-point :menu menu :label label :position position :symbol symbol))(defun draw-point (point view-port plot)   (il:* il:|;;| "Draw a glyph at POINT-POSITION.  SYMBOL is the glyph to be drawn.")   (let ((stream (vp-parent-stream view-port))         (stream-subregion (vp-stream-subregion view-port))         (symbol (point-symbol point))         (stream-point (world-to-stream (point-position point)                              view-port)))        (clipped-plot-at stream-point symbol stream stream-subregion)        (if (eq stream (window-dsp (plot-window plot)))            (setf (point-stream-position point)                  stream-point))))(defun erase-point (point view-port plot)   (il:* il:|;;| "Erase POINT, using cached stream coordinates")   (clipped-plot-at (point-stream-position point)          (point-symbol point)          (vp-parent-stream view-port)          (vp-stream-subregion view-port)          boole-andc1))(defun highlight-point (point view-port plot)   (il:* il:\; "Edited  5-May-87 17:56 by jop")   (il:* il:|;;| "Highlight POINT")   (let* ((symbol (point-symbol point))          (stream-position (point-stream-position point))          (glyph-width (bitmap-width symbol))          (glyph-height (bitmap-height symbol))          (x-offset (- (position-x stream-position)                       (truncate glyph-width 2)))          (y-offset (- (position-y stream-position)                       (truncate glyph-height 2))))         (clipped-bltshade *black-shade* (vp-parent-stream view-port)                (vp-stream-subregion view-port)                :destination-left x-offset :destination-bottom y-offset :width glyph-width :height                 glyph-height :operation boole-xor)))(defun extent-of-point (point plot)   (declare (ignore plot))   (point-position point))(defun distance-to-point (point stream-position plot)   (l1-metric (point-stream-position point)          stream-position))(defun label-point (point plot)   (il:* il:|;;| "Label a POINT")   (let ((view-port (plot-view-port plot))         (text-object (plot-object-prop point :label-object)))        (il:* il:|;;| "Displace Label to right of point object")        (if text-object            (draw-plot-object text-object view-port plot)            (let* ((label (point-label point))                   (position (point-position point))                   (label-position (make-position (+ (position-x position)                                                     (* 2 (stream-to-world-length-x                                                           (bitmap-width (point-symbol point))                                                           view-port)))                                          (position-y position))))                  (setq text-object (make-text label-position label :font *small-plot-font*))                  (draw-plot-object text-object view-port plot)                  (il:* il:|;;| "CACHE LABEL ON PROP LIST OF OBJECT")                  (setf (plot-object-prop point :label-object)                        text-object)))))(defun move-point (point dx dy plot)   (let ((position (point-position point)))        (incf (position-x position)              dx)        (incf (position-y position)              dy)))(defun copy-point (point)   (let ((new-point (%copy-point point)))        (setf (point-position new-point)              (copy-position (point-position point)))        (setf (point-stream-position new-point)              nil)        new-point))(defun put-point (point stream)   (prin1 (point-position point)          stream)   (write-char #\Space stream)   (prin1 (bitmap-to-symbol (point-symbol point))          stream))(defun get-point (point stream)   (setf (point-position point)         (read stream))   (setf (point-symbol point)         (symbol-to-bitmap (read stream))))(defun plot-point (plot position &key label (symbol *star*)                            menu no-update-p)   (il:* il:|;;| "User entry point.  Add a point to PLOT, at world position POSITION, with Label LABEL and plotting symbol SYMBOL")   (add-plot-object (make-point position :symbol symbol :label label :menu menu)          plot no-update-p))(defun plot-points (plot positions &key labels (symbol *star*)                             menu no-update-p)   (il:* il:|;;| "User Entry Point.  Draw the POINTs at POSITIONS in a Plotting WINDOW.")   (let ((points (pt:with-collection (let ((label labels))                                          (dolist (position positions)                                              (pt:collect (make-point position :symbol symbol :label                                                                 (car label)                                                                 :menu menu))                                              (setq label (cdr label)))))))        (add-plot-objects points plot no-update-p)))(defun change-point-symbol (point plot &optional new-sym)   (when (null new-sym)       (print-plot-prompt "Indicate new symbol" plot)       (setq new-sym (pop-up-menu (il:constant (make-symbol-menu))))       (print-plot-prompt "" plot))   (when new-sym       (let ((view-port (plot-view-port plot)))            (erase-plot-object point view-port plot)            (setf (point-symbol point)                  new-sym)            (draw-plot-object point view-port plot))))(il:* il:|;;| "Curves")(define-plot-object curve :instance-vars (positions stream-positions style)   :methods (:label-fn label-generic)   :menu-items (("Width" change-curve-width "Change width")                ("Dashing" change-curve-dashing "Change dashing")))(defun make-curve (positions &key (style (make-line-style))                             label menu)   (if (null positions)       (error "A curve must have at least one position"))   (%make-curve :menu menu :label label :positions positions :style (if (integerp style)                                                                        (make-line-style :width style                                                                               )                                                                        style)))(defun draw-curve (curve view-port plot)   (il:* il:|;;| "Draw a series of connected lines in VIEW-PORT.")   (let* ((stream (vp-parent-stream view-port))          (stream-positions (mapcar #'(lambda (position)                                             (world-to-stream position view-port))                                   (curve-positions curve)))          (style (curve-style curve))          (line-width (* (stream-scale stream)                         (style-width style))))         (connect-positions stream-positions stream (vp-stream-subregion view-port)                boole-1 line-width (style-color style)                (style-dashing style))         (if (eq stream (window-dsp (plot-window plot)))             (setf (curve-stream-positions curve)                   stream-positions))))(defun erase-curve (curve view-port plot)   (il:* il:|;;| "Erase the CURVEOBJECT, using the cached stream coordinates")   (let* ((stream (vp-parent-stream view-port))          (style (curve-style curve))          (line-width (* (stream-scale stream)                         (+ 2 (style-width style)))))         (connect-positions (curve-stream-positions curve)                stream                (vp-stream-subregion view-port)                boole-andc1 line-width (style-color style)                nil)))(defun highlight-curve (curve view-port plot)   (il:* il:\; "Edited  5-May-87 17:55 by jop")   (il:* il:|;;|  "Highlight the CURVEOBJECT, by redrawing in invert mode with slightly fatter lines")   (let* ((stream (vp-parent-stream view-port))          (style (curve-style curve))          (line-width (* (stream-scale stream)                         (+ 2 (style-width style)))))         (connect-positions (curve-stream-positions curve)                stream                (vp-stream-subregion view-port)                boole-xor line-width (style-color style)                nil)))(defun extent-of-curve (curve)   (il:* il:|;;| "Assumes each curve has at least one point")   (positions-list-extent (curve-positions curve)))(defun distance-to-curve (curve stream-position plot)   (positions-list-distance (curve-stream-positions curve)          stream-position))(defun move-curve (curve dx dy plot)   (let ((positions (curve-positions curve)))        (dolist (position positions)            (incf (position-x position)                  dx)            (incf (position-y position)                  dy))))(defun copy-curve (curve)   (il:* il:|;;| "Copyfn for CURVE objects")   (let ((new-curve (%copy-curve curve)))        (setf (curve-positions new-curve)              (mapcar #'(lambda (position)                               (copy-position position))                     (curve-positions curve)))        (setf (curve-stream-positions new-curve)              nil)        (setf (curve-style new-curve)              (copy-line-style (curve-style curve)))        new-curve))(defun put-curve (curve stream)   (prin1 (curve-positions curve)          stream)   (write-char #\Space stream)   (prin1 (curve-style curve)          stream))(defun get-curve (curve stream)   (setf (curve-positions curve)         (read stream))   (setf (curve-style curve)         (read stream)))(defun plot-curve (plot positions &key label (style 1)                            menu no-update-p)   (il:* il:|;;| "User Entry Point.  Draw a piecewise linear curve in PLOT.  Style is either the line width to use or a list (width dashing color).  POSITIONS is a list of positions to be connected.")   (add-plot-object (make-curve positions :style style :label label :menu menu)          plot no-update-p))(defun change-curve-width (curve plot &optional new-width)   (change-style-width new-width (curve-style curve)          curve plot))(defun change-curve-dashing (curve plot &optional new-dashing)   (change-style-dashing new-dashing (curve-style curve)          curve plot))(il:* il:|;;| "Polygons")(define-plot-object polygon :instance-vars (positions stream-positions style)   :methods (:label-fn label-generic)   :menu-items (("Width" change-polygon-width "Change width")                ("Dashing" change-polygon-dashing "Change dashing")))(defun make-polygon (positions &key (style (make-line-style))                               label menu)   (if (null positions)       (error "A polygon must have at least one position"))   (%make-polygon :menu menu :label label :positions positions :style (if (integerp style)                                                                          (make-line-style :width                                                                                  style)                                                                          style)))(defun draw-polygon (polygon view-port plot)   (il:* il:|;;| "Draw a series of connected lines in VIEW-PORT.")   (let* ((stream (vp-parent-stream view-port))          (stream-positions (mapcar #'(lambda (position)                                             (world-to-stream position view-port))                                   (polygon-positions polygon)))          (style (polygon-style polygon))          (line-width (* (stream-scale stream)                         (style-width style)))          (dashing (style-dashing style)))         (connect-positions stream-positions stream (vp-stream-subregion view-port)                boole-1 line-width (style-color style)                (style-dashing style)                t)         (if (eq stream (window-dsp (plot-window plot)))             (setf (polygon-stream-positions polygon)                   stream-positions))))(defun erase-polygon (polygon view-port plot)   (il:* il:|;;| "Erase the CURVEOBJECT, using the cached stream coordinates")   (let* ((stream (vp-parent-stream view-port))          (style (polygon-style polygon))          (line-width (* (stream-scale stream)                         (+ 2 (style-width style)))))         (connect-positions (polygon-stream-positions polygon)                stream                (vp-stream-subregion view-port)                boole-andc1 line-width (style-color style)                nil t)))(defun highlight-polygon (polygon view-port plot)                                                        (il:* il:\; "Edited  5-May-87 17:55 by jop")   (let* ((stream (vp-parent-stream view-port))          (style (polygon-style polygon))          (line-width (* (stream-scale stream)                         (+ 2 (style-width style)))))         (connect-positions (polygon-stream-positions polygon)                stream                (vp-stream-subregion view-port)                boole-xor line-width (style-color style)                nil t)))(defun extent-of-polygon (polygon)   (il:* il:|;;| "Assumes each curve has at least one point")   (positions-list-extent (polygon-positions polygon)))(defun distance-to-polygon (polygon stream-position plot)   (positions-list-distance (polygon-stream-positions polygon)          stream-position))(defun move-polygon (polygon dx dy plot)   (let ((positions (polygon-positions polygon)))        (dolist (position positions)            (incf (position-x position)                  dx)            (incf (position-y position)                  dy))))(defun copy-polygon (polygon)   (let ((new-polygon (%copy-polygon polygon)))        (setf (polygon-positions new-polygon)              (mapcar #'(lambda (position)                               (copy-position position))                     (polygon-positions polygon)))        (setf (polygon-stream-positions new-polygon)              nil)        (setf (polygon-style new-polygon)              (copy-line-style (polygon-style polygon)))        new-polygon))(defun put-polygon (polygon stream)   (prin1 (polygon-positions polygon)          stream)   (write-char #\Space stream)   (prin1 (polygon-style polygon)          stream))(defun get-polygon (polygon stream)   (setf (polygon-positions polygon)         (read stream))   (setf (polygon-style polygon)         (read stream)))(defun plot-polygon (plot positions &key label (style 1)                              menu no-update-p)   (il:* il:|;;| "User Entry Point.  Draw a piecewise linear polygon in PLOT.  Style is either the line width to use or a list (width dashing color).  POSITIONS is a list of positions to be connected by a closed set of lines.")   (add-plot-object (make-polygon positions :style style :label label :menu menu)          plot no-update-p))(defun change-polygon-width (polygon plot &optional new-width)   (change-style-width new-width (polygon-style polygon)          polygon plot))(defun change-polygon-dashing (polygon plot &optional new-dashing)   (change-style-dashing new-dashing (polygon-style polygon)          polygon plot))(il:* il:|;;| "Filled rectangles")(define-plot-object rectangle :instance-vars (left bottom width height border-width texture                                                        stream-left stream-bottom stream-width                                                        stream-height)   :methods (:label-fn label-generic)   :menu-items (("Border" change-rectangle-border "Change border width")                ("Texture" change-rectangle-texture "Change rectangle texture")))(defun rectangle-right (rectangle)   (+ (rectangle-left rectangle)      (rectangle-width rectangle)))(defun rectangle-stream-right (rectangle)   (+ (rectangle-stream-left rectangle)      (rectangle-stream-width rectangle)))(defun rectangle-top (rectangle)   (+ (rectangle-bottom rectangle)      (rectangle-height rectangle)))(defun rectangle-stream-top (rectangle)   (+ (rectangle-stream-bottom rectangle)      (rectangle-stream-height rectangle)))(defun make-rectangle (left bottom width height &key label (border-width 1)                                (texture *shade-3*)                                menu)   (%make-rectangle :menu menu :label label :left left :bottom bottom :width width :height height           :border-width border-width :texture texture))(defun draw-rectangle (rectangle view-port plot)   (let* ((stream (vp-parent-stream view-port))          (stream-subregion (vp-stream-subregion view-port))          (texture (rectangle-texture rectangle))          (border-width (* (stream-scale stream)                           (rectangle-border-width rectangle)))          (stream-left (world-to-stream-x (rectangle-left rectangle)                              view-port))          (stream-bottom (world-to-stream-y (rectangle-bottom rectangle)                                view-port))          (stream-width (- (world-to-stream-x (+ (rectangle-left rectangle)                                                 (rectangle-width rectangle))                                  view-port)                           stream-left))          (stream-height (- (world-to-stream-y (+ (rectangle-bottom rectangle)                                                  (rectangle-height rectangle))                                   view-port)                            stream-bottom))          (stream-right (+ stream-left stream-width))          (stream-top (+ stream-bottom stream-height)))         (clipped-bltshade texture stream stream-subregion :destination-left stream-left                 :destination-bottom stream-bottom :width stream-width :height stream-height                 :operation boole-ior)         (stream-move-to stream-left stream-bottom stream)         (clipped-draw-to stream-right stream-bottom stream stream-subregion :width border-width                 :operation boole-1)         (clipped-draw-to stream-right stream-top stream stream-subregion :width border-width                 :operation boole-1)         (clipped-draw-to stream-left stream-top stream stream-subregion :width border-width                 :operation boole-1)         (clipped-draw-to stream-left stream-bottom stream stream-subregion :width border-width                 :operation boole-1)         (when (eq stream (window-dsp (plot-window plot)))             (setf (rectangle-stream-left rectangle)                   stream-left)             (setf (rectangle-stream-bottom rectangle)                   stream-bottom)             (setf (rectangle-stream-width rectangle)                   stream-width)             (setf (rectangle-stream-height rectangle)                   stream-height))))(defun erase-rectangle (rectangle view-port plot)   (let* ((stream (vp-parent-stream view-port))          (stream-subregion (vp-stream-subregion view-port))          (texture (rectangle-texture rectangle))          (border-width (* (stream-scale stream)                           (rectangle-border-width rectangle)))          (stream-left (rectangle-stream-left rectangle))          (stream-bottom (rectangle-stream-bottom rectangle))          (stream-width (rectangle-stream-width rectangle))          (stream-height (rectangle-stream-height rectangle))          (stream-right (+ stream-left stream-width))          (stream-top (+ stream-bottom stream-height)))         (clipped-bltshade texture stream stream-subregion :destination-left stream-left                 :destination-bottom stream-bottom :width stream-width :height stream-height                 :operation boole-xor)         (stream-move-to stream-left stream-bottom stream)         (clipped-draw-to stream-right stream-bottom stream stream-subregion :width border-width                 :operation boole-andc1)         (clipped-draw-to stream-right stream-top stream stream-subregion :width border-width                 :operation boole-andc1)         (clipped-draw-to stream-left stream-top stream stream-subregion :width border-width                 :operation boole-andc1)         (clipped-draw-to stream-left stream-bottom stream stream-subregion :width border-width                 :operation boole-andc1)))(defun highlight-rectangle (rectangle view-port plot)   (let* ((stream (vp-parent-stream view-port))          (stream-subregion (vp-stream-subregion view-port))          (texture (rectangle-texture rectangle))          (border-width (* (stream-scale stream)                           (+ 2 (rectangle-border-width rectangle))))          (stream-left (rectangle-stream-left rectangle))          (stream-bottom (rectangle-stream-bottom rectangle))          (stream-width (rectangle-stream-width rectangle))          (stream-height (rectangle-stream-height rectangle))          (stream-right (+ stream-left stream-width))          (stream-top (+ stream-bottom stream-height)))         (clipped-bltshade *black-shade* stream stream-subregion :destination-left stream-left                 :destination-bottom stream-bottom :width stream-width :height stream-height                 :operation boole-xor)         (stream-move-to stream-left stream-bottom stream)         (clipped-draw-to stream-right stream-bottom stream stream-subregion :width border-width                 :operation boole-xor)         (clipped-draw-to stream-right stream-top stream stream-subregion :width border-width                 :operation boole-xor)         (clipped-draw-to stream-left stream-top stream stream-subregion :width border-width                 :operation boole-xor)         (clipped-draw-to stream-left stream-bottom stream stream-subregion :width border-width                 :operation boole-xor)))(defun extent-of-rectangle (rectangle)   (make-extent :min-x (rectangle-left rectangle)          :max-x          (rectangle-right rectangle)          :min-y          (rectangle-bottom rectangle)          :max-y          (rectangle-top rectangle)))(defun distance-to-rectangle (rectangle stream-position plot)   (let ((stream-x (position-x stream-position))         (stream-y (position-y stream-position))         (stream-left (rectangle-stream-left rectangle))         (stream-bottom (rectangle-stream-bottom rectangle))         (stream-right (rectangle-stream-right rectangle))         (stream-top (rectangle-stream-top rectangle))         (inside-p nil)         x-closest y-closest)        (setq x-closest (cond                           ((> stream-x stream-right)                            stream-right)                           ((< stream-x stream-left)                            stream-left)                           (t (if (or (> stream-y stream-top)                                      (< stream-y stream-bottom))                                  (il:* il:|;;| "outside ")                                  stream-x                                  (il:* il:|;;| "Inside ")                                  (progn (setq inside-p t)                                         (if (< (min (- stream-top stream-y)                                                     (- stream-y stream-bottom))                                                (min (- stream-right stream-x)                                                     (- stream-x stream-left)))                                             (il:* il:|;;| "closer  to top or bottom")                                             stream-x                                             (if (< (- stream-right stream-x)                                                    (- stream-x stream-left))                                                 (il:* il:|;;| "Closest to right edge")                                                 stream-right                                                 (il:* il:|;;| "Closest to left edge")                                                 stream-left)))))))        (setq y-closest (cond                           ((> stream-y stream-top)                            stream-top)                           ((< stream-y stream-bottom)                            stream-bottom)                           (t (if (or (> stream-x stream-right)                                      (< stream-x stream-left))                                  (il:* il:|;;| "outside ")                                  stream-y                                  (il:* il:|;;| "Inside ")                                  (progn (setq inside-p t)                                         (if (< (min (- stream-right stream-x)                                                     (- stream-x stream-left))                                                (min (- stream-top stream-y)                                                     (- stream-y stream-bottom)))                                             (il:* il:|;;| "closer  to right or left")                                             stream-y                                             (if (< (- stream-top stream-y)                                                    (- stream-y stream-bottom))                                                 (il:* il:|;;| "Closest to right edge")                                                 stream-top                                                 (il:* il:|;;| "Closest to left edge")                                                 stream-bottom)))))))        (let ((raw-distance (l1-metric-xy stream-position x-closest y-closest)))             (if inside-p                 (il:* il:|;;| "Hack to deal with the case of adjacent rectangles.  Bonus subtracted from metric if cursor inside rectangle")                 (- raw-distance 2)                 raw-distance))))(defun move-rectangle (rectangle dx dy plot)   (incf (rectangle-left rectangle)         dx)   (incf (rectangle-bottom rectangle)         dy))(defun copy-rectangle (rectangle)   (il:* il:|;;| "Copyfn for CURVE objects")   (let ((new-rectangle (%copy-rectangle rectangle)))        (setf (rectangle-stream-left new-rectangle)              nil)        (setf (rectangle-stream-bottom new-rectangle)              nil)        (setf (rectangle-stream-width new-rectangle)              nil)        (setf (rectangle-stream-height new-rectangle)              nil)        new-rectangle))(defun put-rectangle (rectangle stream)   (prin1 (rectangle-left rectangle)          stream)   (write-char #\Space stream)   (prin1 (rectangle-bottom rectangle)          stream)   (write-char #\Space stream)   (prin1 (rectangle-width rectangle)          stream)   (write-char #\Space stream)   (prin1 (rectangle-height rectangle)          stream)   (write-char #\Space stream)   (prin1 (rectangle-border-width rectangle)          stream)   (write-char #\Space stream)   (prin1 (rectangle-texture rectangle)          stream))(defun get-rectangle (rectangle stream)   (setf (rectangle-left rectangle)         (read stream))   (setf (rectangle-bottom rectangle)         (read stream))   (setf (rectangle-width rectangle)         (read stream))   (setf (rectangle-height rectangle)         (read stream))   (setf (rectangle-border-width rectangle)         (read stream))   (setf (rectangle-texture rectangle)         (read stream)))(defun plot-rectangle (plot left bottom width height &key label (texture *shade-3*)                                (border-width 1)                                menu no-update-p)   (add-plot-object (make-rectangle left bottom width height :label label :border-width border-width                           :texture texture :menu menu)          plot no-update-p))(defun change-rectangle-border (rectangle plot &optional new-width)   (il:* il:|;;| "Assumes an open plot-window")   (when (null new-width)       (print-plot-prompt "Indicate new border width" plot)       (setq new-width (il:rnumber nil nil nil nil t nil t))       (print-plot-prompt "" plot))   (when new-width       (let ((view-port (plot-view-port plot)))            (erase-plot-object rectangle view-port plot)            (setf (rectangle-border-width rectangle)                  new-width)            (draw-plot-object rectangle view-port plot))))(defun change-rectangle-texture (rectangle plot &optional new-texture)   (when (null new-texture)       (print-plot-prompt "Indicate new texture" plot)       (setq new-texture (pop-up-menu (il:constant (make-texture-menu))))       (print-plot-prompt "" plot))   (when new-texture       (let ((view-port (plot-view-port plot)))            (erase-plot-object rectangle view-port plot)            (setf (rectangle-texture rectangle)                  new-texture)            (draw-plot-object rectangle view-port plot))))(il:* il:|;;| "Text")(define-plot-object text :instance-vars (position stream-position string font)   :methods (:label-fn plot-object-error))(defun make-text (position string &key (font *small-plot-font*)                            menu)   (%make-text :menu menu :position position :string (string string)          :font font))(defun draw-text (text-object view-port plot)   (let* ((stream (vp-parent-stream view-port))          (position (text-position text-object))          (stream-x (world-to-stream-x (position-x position)                           view-port))          (stream-y (world-to-stream-y (position-y position)                           view-port))          (stream-font (stream-font stream)))         (setf (stream-font stream)               (text-font text-object))         (stream-move-to stream-x stream-y stream)         (clipped-princ (text-string text-object)                stream                (vp-stream-subregion view-port))         (setf (stream-font stream)               stream-font)         (if (eq stream (window-dsp (plot-window plot)))             (setf (text-stream-position text-object)                   (make-position stream-x stream-y)))))(defun erase-text (text-object view-port plot)   (il:* il:|;;| "ERASE the TEXTOBJECT")   (let* ((stream (vp-parent-stream view-port))          (stream-position (text-stream-position text-object))          (stream-x (position-x stream-position))          (stream-y (position-y stream-position))          (stream-font (stream-font stream)))         (setf (stream-font stream)               (text-font text-object))         (stream-move-to stream-x stream-y stream)         (let ((string-region (string-region (text-string text-object)                                     stream)))              (clipped-bltshade (stream-texture stream)                     stream                     (vp-stream-subregion view-port)                     :destination-left                     (region-left string-region)                     :destination-bottom                     (region-bottom string-region)                     :width                     (region-width string-region)                     :height                     (region-height string-region)                     :operation boole-1))         (setf (stream-font stream)               stream-font)))(defun highlight-text (text-object view-port plot)   (il:* il:|;;| "ERASE the TEXTOBJECT")   (let* ((stream (vp-parent-stream view-port))          (stream-position (text-stream-position text-object))          (stream-x (position-x stream-position))          (stream-y (position-y stream-position))          (stream-font (stream-font stream)))         (setf (stream-font stream)               (text-font text-object))         (stream-move-to stream-x stream-y stream)         (let ((string-region (string-region (text-string text-object)                                     stream)))              (clipped-bltshade *black-shade* stream (vp-stream-subregion view-port)                     :destination-left                     (region-left string-region)                     :destination-bottom                     (region-bottom string-region)                     :width                     (region-width string-region)                     :height                     (region-height string-region)                     :operation boole-xor))         (setf (stream-font stream)               stream-font)))(defun extent-of-text (text-object)   (text-position text-object))(defun distance-to-text (text-object stream-position plot)   (l1-metric (text-stream-position text-object)          stream-position))(defun move-text (text-object dx dy plot)   (let ((position (text-position text-object)))        (incf (position-x position)              dx)        (incf (position-y position)              dy)))(defun copy-text (text)   (il:* il:|;;| "Copyfn for CURVE objects")   (let ((new-text (%copy-text text)))        (setf (text-position new-text)              (copy-position (text-position text)))        (setf (text-stream-position new-text)              nil)        (setf (text-string new-text)              (copy-seq (text-string text)))        new-text))(defun put-text (text stream)   (prin1 (text-position text)          stream)   (write-char #\Space stream)   (prin1 (text-string text)          stream)   (write-char #\Space stream)   (print-font (text-font text)          stream))(defun get-text (text stream)   (setf (text-position text)         (read stream))   (setf (text-string text)         (read stream))   (setf (text-font text)         (read-font stream)))(defun plot-text (plot position text &key (font *small-plot-font*)                           menu no-update-p)   (add-plot-object (make-text position text :font font :menu menu)          plot no-update-p))(il:* il:|;;| "Compound objects")(define-plot-object compound :instance-vars (components)   :methods (:label-fn label-generic))(defun make-compound (components &key label menu)   (if (null components)       (error "A compound must have at least one component"))   (%make-compound :menu menu :label label :components components))(defun draw-compound (compound view-port plot)   (dolist (object (compound-components compound))       (draw-plot-object object view-port plot)))(defun erase-compound (compound view-port plot)   (dolist (object (compound-components compound))       (erase-plot-object object view-port plot)))(defun highlight-compound (compound view-port plot)   (dolist (object (compound-components compound))       (highlight-plot-object object view-port plot)))(defun extent-of-compound (compound plot)   (plot-objects-extent (compound-components compound)          plot))(defun distance-to-compound (compound stream-position plot)   (let* ((components (compound-components compound))          (min (distance-to-plot-object (car components)                      stream-position plot)))         (dolist (part (cdr components)                       min)             (let ((new-min (distance-to-plot-object part stream-position plot)))                  (if (< new-min min)                      (setq min new-min))))))(defun move-compound (compound dx dy plot)   (dolist (object (compound-components compound))       (move-plot-object object dx dy plot)))(defun copy-compound (compound)   (il:* il:|;;| "Copyfn for CURVE objects")   (let ((new-compound (%copy-compound compound)))        (setf (compound-components new-compound)              (mapcar #'(lambda (object)                               (copy-plot-object object))                     (compound-components compound)))        new-compound))(defun put-compound (compound stream)   (prin1 (length (compound-components compound))          stream)   (write-char #\Space stream)   (dolist (object (compound-components compound))       (print-plot-object object stream)       (write-char #\Space stream)))(defun get-compound (compound stream)   (let ((n-objects (read stream)))        (setf (compound-components compound)              (pt:with-collection (dotimes (i n-objects)                                      (pt:collect (read-plot-object stream)))))))(defun plot-compound (plot &rest args)   (let* ((first-keyword-arg (position-if #'(lambda (x)                                                   (member x '(:label :menu :no-update-p)))                                    args))          (components (subseq args 0 (or first-keyword-arg (length args))))          (label (cdr (member :label args)))          (menu (cdr (member :menu args)))          (no-update-p (cdr (member :no-update-p args))))         (add-plot-object (make-compound components :label label :menu menu)                plot no-update-p)))(il:* il:|;;| "Analytic lines")(define-plot-object line :instance-vars (slope constant infinite-slope-p style stream-slope                                                    stream-constant stream-position-1                                                    stream-position-2)   :methods (:draw-fn draw-analytic-line :erase-fn erase-analytic-line :label-fn label-generic                    :move-fn plot-object-error)   :menu-items (("Width" change-line-width "Change width")                ("Dashing" change-line-dashing "Change dashing")))(defun make-line (slope constant &key extent-fn label (style (make-line-style))                            menu)   (il:* il:|;;| "Create a line plot object")   (%make-line :menu menu :label label :slope (or slope 0.0)          :constant constant :infinite-slope-p (null slope)          :style          (if (integerp style)              (make-line-style :width style)              style)          :prop-list          (if extent-fn (list :extent-fn extent-fn))))(defun draw-analytic-line (line view-port plot)   (let* ((stream (vp-parent-stream view-port))          (stream-subregion (vp-stream-subregion view-port))          (style (line-style line))          (linewidth (* (stream-scale stream)                        (style-width style)))          (infinite-slope-p (line-infinite-slope-p line))          (slope (line-slope line))          (constant (line-constant line))          (x1 (if infinite-slope-p                  constant                  (plot-x-lower plot)))          (y1 (if infinite-slope-p                  (plot-y-lower plot)                  (+ constant (* slope x1))))          (x2 (if infinite-slope-p                  constant                  (plot-x-upper plot)))          (y2 (if infinite-slope-p                  (plot-y-upper plot)                  (+ constant (* slope x2))))          (stream-position-1 (make-position (world-to-stream-x x1 view-port)                                    (world-to-stream-y y1 view-port)))          (stream-position-2 (make-position (world-to-stream-x x2 view-port)                                    (world-to-stream-y y2 view-port)))          (stream-slope (unless infinite-slope-p                            (* slope (/ (lt-m (vp-world-to-stream-y view-port))                                        (lt-m (vp-world-to-stream-x view-port))))))          (stream-constant (if infinite-slope-p                               (world-to-stream-x constant view-port)                               (- (world-to-stream-y constant view-port)                                  (* stream-slope (lt-a (vp-world-to-stream-x view-port)))))))         (clipped-draw-between stream-position-1 stream-position-2 stream stream-subregion :width                 linewidth :operation boole-1 :color (style-color style)                :dashing                (style-dashing style))         (when (eq stream (window-dsp (plot-window plot)))             (setf (line-stream-slope line)                   stream-slope)             (setf (line-stream-constant line)                   stream-constant)             (setf (line-stream-position-1 line)                   stream-position-1)             (setf (line-stream-position-2 line)                   stream-position-2))))(defun erase-analytic-line (line view-port plot)   (let* ((stream (vp-parent-stream view-port))          (stream-subregion (vp-stream-subregion view-port))          (style (line-style line))          (linewidth (* (stream-scale stream)                        (+ 2 (style-width style))))          (stream-position-1 (line-stream-position-1 line))          (stream-position-2 (line-stream-position-2 line)))         (clipped-draw-between stream-position-1 stream-position-2 stream stream-subregion :width                 linewidth :operation boole-andc1 :color (style-color style)                :dashing                (style-dashing style))))(defun highlight-line (line view-port plot)   (let* ((stream (vp-parent-stream view-port))          (stream-subregion (vp-stream-subregion view-port))          (style (line-style line))          (linewidth (* (stream-scale stream)                        (+ 2 (style-width style))))          (stream-position-1 (line-stream-position-1 line))          (stream-position-2 (line-stream-position-2 line)))         (clipped-draw-between stream-position-1 stream-position-2 stream stream-subregion :width                 linewidth :operation boole-xor :color (style-color style)                :dashing                (style-dashing style))))(defun distance-to-line (line stream-position plot)   (il:* il:|;;| "Assumes use of the L1 metric")   (let ((x0 (position-x stream-position))         (y0 (position-y stream-position))         (stream-slope (line-stream-slope line))         (stream-constant (line-stream-constant line)))        (truncate (if (line-infinite-slope-p line)                      (abs (- x0 stream-constant))                      (il:* il:|;;|              "Compute the intersection of the perpendicular going through (x0 , y0) and the line. ")                      (let* ((mp (- (/ 1.0 stream-slope)))                             (bp (- y0 (* mp x0)))                             (xi (/ (- bp stream-constant)                                    (- stream-slope mp)))                             (yi (+ (* mp xi)                                    bp)))                            (l1-metric-xy stream-position xi yi))))))(defun copy-line (line)   (il:* il:|;;| "Copyfn for CURVE objects")   (let ((new-line (%copy-line line)))        (setf (line-style new-line)              (copy-line-style (line-style line)))        (setf (line-stream-slope new-line)              nil)        (setf (line-stream-constant new-line)              nil)        (setf (line-stream-position-1 new-line)              nil)        (setf (line-stream-position-2 new-line)              nil)        new-line))(defun extent-of-line (line plot)   (let ((extent-fn (plot-object-prop line :extent-fn)))        (if extent-fn (funcall extent-fn plot))))(defun put-line (line stream)   (prin1 (line-slope line)          stream)   (write-char #\Space stream)   (prin1 (line-constant line)          stream)   (write-char #\Space stream)   (prin1 (line-infinite-slope-p line)          stream)   (write-char #\Space stream)   (prin1 (line-style line)          stream))(defun get-line (line stream)   (setf (line-slope line)         (read stream))   (setf (line-constant line)         (read stream))   (setf (line-infinite-slope-p line)         (read stream))   (setf (line-style line)         (read stream)))(defun plot-line (plot slope constant &key label (style 1)                           menu no-update-p)   (add-plot-object (make-line slope constant :label label :style style :menu menu)          plot no-update-p))(defun change-line-width (line plot &optional new-width)   (change-style-width new-width (line-style line)          line plot))(defun change-line-dashing (line plot &optional new-dashing)   (change-style-dashing new-dashing (line-style line)          line plot))(il:* il:|;;| "Graphs")(define-plot-object graph :instance-vars (fn n-samples style stream-positions)   :methods (:label-fn label-generic :move-fn plot-object-error :put-fn plot-object-error :get-fn                    plot-object-error)   :menu-items (("Width" change-graph-width "Change width")                ("Dashing" change-graph-dashing "Change dashing")))(defun make-graph (fn &key (n-samples 100)                          extent-fn label (style (make-line-style))                          menu)   (%make-graph :menu menu :label label :fn fn :n-samples n-samples :style (if (integerp style)                                                                               (make-line-style                                                                                :width style)                                                                               style)          :prop-list          (if extent-fn (list :extent-fn extent-fn))))(defun draw-graph (graph view-port plot)   (let* ((stream (vp-parent-stream view-port))          (style (graph-style graph))          (line-width (* (stream-scale stream)                         (style-width style)))          (stream-positions (let ((x-upper (plot-x-upper plot))                                  (x-lower (plot-x-lower plot))                                  (graph-fn (graph-fn graph))                                  (n-samples (graph-n-samples graph)))                                 (let ((inc (/ (- x-upper x-lower)                                               (1- n-samples)))                                       (x x-lower))                                      (pt:with-collection (dotimes (i (1- n-samples))                                                              (pt:collect (make-position                                                                           (world-to-stream-x x                                                                                   view-port)                                                                           (world-to-stream-y                                                                            (funcall graph-fn x)                                                                            view-port)))                                                              (incf x inc))                                             (pt:collect (make-position (world-to-stream-x x-upper                                                                                view-port)                                                                (world-to-stream-y (funcall graph-fn                                                                                          x-upper)                                                                       view-port))))))))         (connect-positions stream-positions stream (vp-stream-subregion view-port)                boole-1 line-width (style-color style)                (style-dashing style))         (if (eq stream (window-dsp (plot-window plot)))             (setf (graph-stream-positions graph)                   stream-positions))))(defun erase-graph (graph view-port plot)   (let* ((stream (vp-parent-stream view-port))          (style (graph-style graph))          (line-width (* (stream-scale stream)                         (+ 2 (style-width style)))))         (connect-positions (graph-stream-positions graph)                stream                (vp-stream-subregion view-port)                boole-andc1 line-width (style-color style)                nil)))(defun highlight-graph (graph view-port plot)   (let* ((stream (vp-parent-stream view-port))          (style (graph-style graph))          (line-width (* (stream-scale stream)                         (+ 2 (style-width style)))))         (connect-positions (graph-stream-positions graph)                stream                (vp-stream-subregion view-port)                boole-xor line-width (style-color style)                nil)))(defun distance-to-graph (graph stream-position plot)   (positions-list-distance (graph-stream-positions graph)          stream-position))(defun copy-graph (graph)   (il:* il:|;;| "Copyfn for CURVE objects")   (let ((new-graph (%copy-graph graph)))        (setf (graph-style new-graph)              (copy-line-style (graph-style graph)))        (setf (graph-stream-positions new-graph)              nil)        new-graph))(defun extent-of-graph (graph plot)   (let ((extent-fn (plot-object-prop graph :extent-fn)))        (if extent-fn (funcall extent-fn plot))))(defun plot-graph (plot fn &optional (n-samples 100)                            label                            (style 1)                            menu no-update-p)   (il:* il:|;;| "User Entry Point.  Draw a piecewise linear curve in PLOT.  Style is either the line width to use or a list (width dashing color).  POSITIONS is a list of positions to be connected.")   (add-plot-object (make-graph fn :n-samples n-samples :style style :label label :menu menu)          plot no-update-p))(defun change-graph-width (graph plot &optional new-width)   (change-style-width new-width (graph-style graph)          graph plot))(defun change-graph-dashing (graph plot &optional new-dashing)   (change-style-dashing new-dashing (graph-style graph)          graph plot))(xcl:define-file-environment "PLOT-OBJECTS" :package "PLOT"   :compiler :compile-file   :readtable "XCL")(il:putprops il:plot-objects il:copyright ("Xerox Corporation" 1988))(il:declare\: il:dontcopy  (il:filemap (nil)))il:stop