(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