58.2 Shapes and Path Visuals
Use circle and rectangle for the two basic shape Visuals, make-path-visual for existing local geometry, and line or polygon for points supplied in a containing coordinate system. The catalogue constructors below reuse ordinary path and group Visuals.
See also Visual Protocols and Groups, Live Endpoints and Mathematical Annotations.
58.2.1 Circle Visuals
procedure
(circle #:id id [ #:center center #:rotation rotation #:scale scale #:opacity opacity #:radius radius #:fill fill #:stroke stroke #:stroke-width stroke-width]) → circle-visual? id : symbol? center : vec2? = origin rotation : finite-real? = 0 scale : scale-factor? = 1 opacity : opacity? = 1 radius : (and/c finite-real? positive?) = 1 fill : any/c = "dodgerblue" stroke : any/c = "black" stroke-width : (and/c finite-real? (>=/c 0)) = 2
The built-in Pict renderer treats fill and stroke as color values and stroke-width as a Pict border width. These style values are stored without adapter-specific validation.
Circle Visuals implement gen:visual, gen:affine-visual, gen:opacity-visual, and gen:stroke-width-visual. The opacity value multiplies the complete rendered circle after renderer dispatch.
procedure
(circle-visual? value) → boolean?
value : any/c
procedure
(circle-visual-radius circle) → (and/c finite-real? positive?)
circle : circle-visual?
Inspect local geometry without rendering it.
> (define disk (circle #:id 'disk #:radius 3/4)) > (circle-visual-radius disk) 3/4
procedure
(circle-visual-fill circle) → any/c
circle : circle-visual?
procedure
(circle-visual-stroke circle) → any/c
circle : circle-visual?
procedure
(circle-visual-stroke-width circle)
→ (and/c finite-real? (>=/c 0)) circle : circle-visual?
58.2.2 Rectangle Visuals
procedure
(rectangle #:id id [ #:center center #:rotation rotation #:scale scale #:opacity opacity #:width width #:height height #:fill fill #:stroke stroke #:stroke-width stroke-width]) → rectangle-visual? id : symbol? center : vec2? = origin rotation : finite-real? = 0 scale : scale-factor? = 1 opacity : opacity? = 1 width : (and/c finite-real? positive?) = 2 height : (and/c finite-real? positive?) = 1 fill : any/c = "goldenrod" stroke : any/c = "black" stroke-width : (and/c finite-real? (>=/c 0)) = 2
The id argument is required. Style values are stored for an adapter to interpret. Rectangle Visuals implement the basic, affine, opacity, and stroke-width Visual protocols. The opacity value multiplies the complete rendered rectangle.
procedure
(rectangle-visual? value) → boolean?
value : any/c
procedure
(rectangle-visual-width rectangle)
→ (and/c finite-real? positive?) rectangle : rectangle-visual?
procedure
(rectangle-visual-height rectangle)
→ (and/c finite-real? positive?) rectangle : rectangle-visual?
procedure
(rectangle-visual-fill rectangle) → any/c
rectangle : rectangle-visual?
procedure
(rectangle-visual-stroke rectangle) → any/c
rectangle : rectangle-visual?
procedure
(rectangle-visual-stroke-width rectangle)
→ (and/c finite-real? (>=/c 0)) rectangle : rectangle-visual?
58.2.3 Path Visuals
A path Visual combines local path-geometry with identity, affine placement, fill, stroke, and cosmetic stroke width. Its geometry may contain line segments, cubic Bézier segments, or both. It implements gen:visual, gen:affine-visual, and gen:opacity-visual.
The Visual’s reference position is the translation component of its affine transform. Its path points remain local model data. Scale and rotation are applied around the local origin before the Visual is translated to its reference position.
procedure
(make-path-visual path #:id id [ #:center center #:rotation rotation #:scale scale #:opacity opacity #:fill fill #:stroke stroke #:stroke-width stroke-width]) → path-visual? path : path-geometry? id : symbol? center : vec2? = origin rotation : finite-real? = 0 scale : scale-factor? = 1 opacity : opacity? = 1 fill : any/c = #f stroke : any/c = "black" stroke-width : (and/c finite-real? (>=/c 0)) = 2
The built-in Pict renderer interprets a false fill as transparent and a false stroke as no outline. Other style values are passed to the Racket drawing backend as color values. Stroke width is cosmetic and measured in output pixels; semantic scale does not multiply it.
Empty path geometry is accepted and produces a transparent one-pixel Pict in the built-in renderer.
procedure
(path-visual? value) → boolean?
value : any/c
procedure
(path-visual-path visual) → path-geometry?
visual : path-visual?
procedure
(path-visual-fill visual) → any/c
visual : path-visual?
procedure
(path-visual-stroke visual) → any/c
visual : path-visual?
procedure
(path-visual-stroke-width visual)
→ (and/c finite-real? (>=/c 0)) visual : path-visual?
procedure
(path-visual-with-path visual path) → path-visual?
visual : path-visual? path : path-geometry?
procedure
(line start end #:id id [ #:rotation rotation #:scale scale #:opacity opacity #:stroke stroke #:stroke-width stroke-width]) → path-visual? start : vec2? end : vec2? id : symbol? rotation : finite-real? = 0 scale : scale-factor? = 1 opacity : opacity? = 1 stroke : any/c = "black" stroke-width : (and/c finite-real? (>=/c 0)) = 2
The constructor uses the midpoint of the two points as the Visual’s reference position and subtracts that midpoint from both stored path points. The local line is therefore centered at the origin. Rotation and scale are applied around that midpoint. The fill style is always #f. The optional opacity value is preserved as semantic global opacity.
For example:
(line (vec2 -2 0) (vec2 2 0) #:id 'axis #:stroke "navy" #:stroke-width 3)
The reference position is the midpoint of the supplied endpoints.
procedure
(polygon vertices #:id id [ #:rotation rotation #:scale scale #:opacity opacity #:fill fill #:stroke stroke #:stroke-width stroke-width]) → path-visual? vertices : (listof vec2?) id : symbol? rotation : finite-real? = 0 scale : scale-factor? = 1 opacity : opacity? = 1 fill : any/c = "cornflowerblue" stroke : any/c = "black" stroke-width : (and/c finite-real? (>=/c 0)) = 2
The constructor computes the center of the vertices’ axis-aligned bounding box and uses it as the Visual’s reference position. It subtracts that center from every stored path point, so scale and rotation occur around the bounding-box center. The constructor does not calculate a polygon centroid.
The closing edge from the last vertex to the first is implicit. Do not repeat the first vertex merely to close the polygon; repeating it adds a zero-length segment before the implicit closing edge. The optional opacity value is stored as semantic global opacity.
58.2.4 Mathematical Shape Catalogue
The shape catalogue provides a compact family of path-backed shapes. Except for the two convenience groups, each constructor returns an ordinary path-visual? with the usual affine placement, opacity, fill, and stroke protocols. They do not introduce renderer-specific leaf classes; the existing path renderer draws their line and cubic geometry, including odd-even holes in annulus.
procedure
(ellipse #:id id [ #:center center #:width width #:height height #:rotation rotation #:scale scale #:opacity opacity #:fill fill #:stroke stroke #:stroke-width stroke-width]) → path-visual? id : symbol? center : vec2? = origin width : (and/c finite-real? positive?) = 2 height : (and/c finite-real? positive?) = 1 rotation : finite-real? = 0 scale : scale-factor? = 1 opacity : opacity? = 1 fill : any/c = "cornflowerblue" stroke : any/c = "black" stroke-width : stroke-width? = 2
procedure
(annulus #:id id [ #:center center #:inner-radius inner-radius #:outer-radius outer-radius #:rotation rotation #:scale scale #:opacity opacity #:fill fill #:stroke stroke #:stroke-width stroke-width]) → path-visual? id : symbol? center : vec2? = origin inner-radius : (and/c finite-real? positive?) = 1/2 outer-radius : (and/c finite-real? positive?) = 1 rotation : finite-real? = 0 scale : scale-factor? = 1 opacity : opacity? = 1 fill : any/c = "cornflowerblue" stroke : any/c = "black" stroke-width : stroke-width? = 2
procedure
(sector #:id id [ #:center center #:radius radius #:start-angle start-angle #:angle angle #:rotation rotation #:scale scale #:opacity opacity #:fill fill #:stroke stroke #:stroke-width stroke-width]) → path-visual? id : symbol? center : vec2? = origin radius : (and/c finite-real? positive?) = 1 start-angle : finite-real? = 0 angle : finite-real? = (/ pi 2) rotation : finite-real? = 0 scale : scale-factor? = 1 opacity : opacity? = 1 fill : any/c = "cornflowerblue" stroke : any/c = "black" stroke-width : stroke-width? = 2
procedure
(regular-polygon #:id id [ #:center center #:sides sides #:radius radius #:start-angle start-angle #:rotation rotation #:scale scale #:opacity opacity #:fill fill #:stroke stroke #:stroke-width stroke-width]) → path-visual? id : symbol? center : vec2? = origin sides : exact-integer? = 5 radius : (and/c finite-real? positive?) = 1 start-angle : finite-real? = (/ pi 2) rotation : finite-real? = 0 scale : scale-factor? = 1 opacity : opacity? = 1 fill : any/c = "cornflowerblue" stroke : any/c = "black" stroke-width : stroke-width? = 2
procedure
(star #:id id [ #:center center #:points points #:outer-radius outer-radius #:inner-radius inner-radius #:start-angle start-angle #:rotation rotation #:scale scale #:opacity opacity #:fill fill #:stroke stroke #:stroke-width stroke-width]) → path-visual? id : symbol? center : vec2? = origin points : exact-integer? = 5 outer-radius : (and/c finite-real? positive?) = 1 inner-radius : (and/c finite-real? positive?) = 1/2 start-angle : finite-real? = (/ pi 2) rotation : finite-real? = 0 scale : scale-factor? = 1 opacity : opacity? = 1 fill : any/c = "gold" stroke : any/c = "black" stroke-width : stroke-width? = 2
procedure
(rounded-rectangle #:id id [ #:center center #:width width #:height height #:corner-radius corner-radius #:rotation rotation #:scale scale #:opacity opacity #:fill fill #:stroke stroke #:stroke-width stroke-width]) → path-visual? id : symbol? center : vec2? = origin width : (and/c finite-real? positive?) = 2 height : (and/c finite-real? positive?) = 1 corner-radius : stroke-width? = 1/5 rotation : finite-real? = 0 scale : scale-factor? = 1 opacity : opacity? = 1 fill : any/c = "cornflowerblue" stroke : any/c = "black" stroke-width : stroke-width? = 2
procedure
(arc-between-points start end #:id id [ #:angle angle #:opacity opacity #:stroke stroke #:stroke-width stroke-width]) → path-visual? start : vec2? end : vec2? id : symbol? angle : finite-real? = (/ pi 2) opacity : opacity? = 1 stroke : any/c = "black" stroke-width : stroke-width? = 2
procedure
(curved-arrow start end #:id id [ #:angle angle #:opacity opacity #:stroke stroke #:stroke-width stroke-width #:tip-length tip-length #:tip-width tip-width]) → group-visual? start : vec2? end : vec2? id : symbol? angle : finite-real? = (/ pi 2) opacity : opacity? = 1 stroke : any/c = "black" stroke-width : stroke-width? = 2 tip-length : (and/c finite-real? positive?) = 3/10 tip-width : (and/c finite-real? positive?) = 1/4
procedure
(double-arrow start end #:id id [ #:rotation rotation #:scale scale #:opacity opacity #:stroke stroke #:stroke-width stroke-width #:tip-length tip-length #:tip-width tip-width]) → arrow-visual? start : vec2? end : vec2? id : symbol? rotation : finite-real? = 0 scale : scale-factor? = 1 opacity : opacity? = 1 stroke : any/c = "black" stroke-width : stroke-width? = 2 tip-length : (and/c finite-real? positive?) = 3/10 tip-width : (and/c finite-real? positive?) = 1/4
procedure
(labeled-point label #:id id [ #:center center #:radius radius #:label-offset label-offset #:font-size font-size #:font-family font-family #:fill fill #:stroke stroke #:stroke-width stroke-width #:color color #:opacity opacity]) → group-visual? label : string? id : symbol? center : vec2? = origin radius : (and/c finite-real? positive?) = 1/10 label-offset : vec2? = (vec2 1/4 1/4) font-size : (and/c finite-real? positive?) = 1/4 font-family : any/c = 'roman fill : any/c = "crimson" stroke : any/c = "firebrick" stroke-width : stroke-width? = 2 color : any/c = stroke opacity : opacity? = 1