1.134 class path

A path is a line going through a set of points. There are two kinds of paths:

polyStraight line segments connect the points
smoothA smooth (curved) line connects the points

The line of a path has a graphical->texture and a graphical->pen (thickness). The first and last point of the path may be connected (path->closed) and the interior of the path may be filled with a colour using path->fill. Class path is a subclass of class joint and therefore may have joint->arrows attached.

How the path gets to a point is determined by the class of the point. A plain point is reached by a straight line. The following subclasses of class point describe other segments, using the same vocabulary as Cairo and SVG paths:

curve_pointA quadratic or cubic Bezier curve
arc_pointAn elliptical arc (as SVG A)
move_pointNo line: start a new sub-path

For example, a closed shape that is a half circle on top of a rectangle:

new(P, path),
send_list(P, append, [ point(0,40), arc_point(80,40, 40),
                       point(80,100), point(0,100) ]),
send(P, closed, @on),
send(P, fill, colour(skyblue)).

Paths can be used for numerous purposes:

1.134.1 Instance variables

path <- closed: bool
If @on, the first and last points are connected. If the path has sub-paths (see class move_point), each of them is closed, unless move_point<-closed says otherwise.

Defaults: @off

path <- fill: colour|gradient|image|{foreground,background}*
Colour, gradient or (repeated) image used to fill the interior of the path. Which parts are interior is determined by path<-fill_rule.

Defaults: @nil (not filled)

path <- fill_rule: {winding,even_odd}
Determines which parts of a path that intersects itself, or that has sub-paths, are inside. Using winding, a point is inside if the path goes around it more often in one direction than in the other. Using even_odd, a point is inside if a ray from it crosses the path an odd number of times. The difference shows for a sub-path inside another one, drawn the same way round: with even_odd it is a hole. The rule is also used by path->inside and for selecting a filled path with the mouse.

Defaults: winding

path <- interpolation: chain*
When kind is smooth, this is a chain of interpolated points. The interpolation is recomputed each time the path has been modified and needs to be painted. See also graphical->request_compute.
See also
path-kind
path <- intervals: 0..100
The number of interpolation-points between each two successive specified points.

Defaults: Resource defined (10).

path <- kind: {poly,smooth}
Determines whether the line is smooth or a collection of line-segments (poly). For smooth path objects, the number of interpolated points is determined by path<->intervals and the chain object holding all interpolated points is available in path<-interpolation.

Defaults: poly (line segments).

See also
path-interpolation
path <- mark: image*
When not @nil, each point of the path is marked using this image. Note that interpolation-points are not marked.

Defaults: @nil

path <- offset: point
Offset to origin. This offset is added to the location of the path<-points of the path if the path is painted. See also path->reference and path->relative_move.
path <- points: chain
Chain of points the line-segments goes through. The class of each point determines how the path gets there from the previous point: a straight line for a plain point, or a curve, arc or jump for a curve_point, arc_point or move_point. These are ignored for smooth paths. The send-method validates and possibly converts all members of the argument chain to be instances of class point and raises the error unexpected_type on failure. On successs, it replaces the path<-points chain of the path with the argument. The argument thus becomes a part of the path object. See also path->initialise.
path <- radius: int
Rounding radius for the corners of poly lines. Only corners between two straight segments are rounded. If the segments are too short, the radius is reduced such that each corner uses at most half of a segment.

Defaults: 0 (non-rounded corners).

1.134.2 Send methods

path ->append: point
Append a point at the end of the path. The point is specified in the graphical<-device coordinate system. path->insert may be used to insert points in the middle or prepend points.
See also
path->insert
path ->compute:
Computes graphical<-area from the path<-points and path<-interpolation from path<-points if path<-kind = smooth.
path ->delete: point
Delete a point from the path. To delete points interactively, see also path<-point.
path ->geometry: x=[int], y=[int], width=[int], height=[int]
Moves and resizes the path to fit the requested bounding-box. Paths may also be resized using path->resize.
path ->initialise: kind=[{poly,smooth}], radius_or_interval=[int], points=[chain]
The first argument specifies the path<-kind. When path<-kind equals smooth, the second argument specifies the path<-intervals. If the points arguments is supplied, the method path->points is invoked using this argument to specify the initial set of control-points.
path ->insert: point, point*
Insert a new point after the second argument. If the second argument is @nil, the point is added as the first point of the chain. For interactive editing, path<-segment may be used to find the point to insert after.
See also
path->append
path ->inside: x=int, y=int
Succeed if the point (X, Y) — in the path's graphical<-device coordinate system — lies inside the area the path encloses, as determined by path<-fill_rule. Each sub-path is implicitly closed, so path<-closed is not consulted: an open polygon can still be probed as a closed region for hit-testing purposes. For smooth paths the test is performed against the interpolated poly-line. Fails silently when the path has fewer than two points.

Companion to graphical->in_event_area, which combines this test with a near-outline distance test to make edge hits work on closed paths as well as open ones.

path ->svg_data: char_array
Replace the points of the path by the path described by SVG path data, the d attribute of an SVG <path> element. All commands (M, L, H, V, C, S, Q, T, A and Z, absolute and relative) are supported. Sets path<-kind to poly and path<-closed to whether the first sub-path is closed. Fails with a syntax error if the data is not valid.
send(P, svg_data, "M10 80 Q 52.5 10, 95 80 T 180 80").
path ->relative_move: diff=point, how=[{offset,points}]
Move the graphical relative to its current position using the X- and Y-values of point. How defines how the path is moved: by adusting its path<-offset (default) or by adjusting each of the path<-points.
path ->set_point: point=point, x=[int], y=[int]
Move a member point. The arguments are the X- and Y-coordinates in the graphical<-device’s coordinate system.

1.134.3 Get methods

path <-distance: point|event|graphical -> int
If the argument is a point object or event object (in which case the event<-position is used), compute the distance of this point to the path-line. If the path is interpolated, the distance to the interpolation is computed.

If the argument is a graphical, use graphical<-distance.

See also line<-distance and graphical->in_event_area.

path <-end: -> point
Position (in graphical<-device coordinate system) of the last point of the path. See also path<-start.
See also
path<-start
path <-point: near=point|event, max_distance=[int] -> point
Return (member) point object that is closest to the given position and within the specified maximum distance (default 10 pixels). When an event is passed, this is translated into the position of the event.

See also path<-segment.

Defaults: The default maximum distance (2nd argument) is 10.

Diagnostics: Fails silently if no such point exist.

path <-segment: near=point|event, accept=[0..] -> point
Return member point that is the start of a line-segment nearest to the indicated position or event graphical<-position. May be used to interactively path->insert new points:
send(Path, click_gesture(left, '', single,
                         message(@receiver, insert,
                                 ?(@event, position, @receiver?device),
                                 ?(@receiver, segment, @event)))).

See also path<-point.

path <-svg_data: -> string
The points of the path as SVG path data. Relative commands and shorthands are written as their absolute equivalent, so the result is not necessarily the string given to path->svg_data.
path <-start: -> point
First point of the path (equivalent to Path?points?head). See also path<-end.
See also
path<-end