geometry synopses

This commit is contained in:
Adrian Mariano 2023-05-02 19:42:44 -04:00
parent 1f88bbadb8
commit da61adbe59
2 changed files with 62 additions and 9 deletions

View file

@ -18,6 +18,7 @@
// Usage:
// pt = is_point_on_line(point, line, [bounded], [eps]);
// Topics: Geometry, Points, Segments
// Synopsis: Determine if a point is on a line, ray or segment.
// Description:
// Determine if the point is on the line segment, ray or segment defined by the two between two points.
// Returns true if yes, and false if not. If bounded is set to true it specifies a segment, with
@ -141,6 +142,7 @@ function _point_left_of_line2d(point, line, eps=EPSILON) =
// Function: is_collinear()
// Usage:
// bool = is_collinear(a, [b, c], [eps]);
// Synopsis: Determine if a points are collinear.
// Topics: Geometry, Points, Collinearity
// Description:
// Returns true if the points `a`, `b` and `c` are co-linear or if the list of points `a` is collinear.
@ -163,6 +165,7 @@ function is_collinear(a, b, c, eps=EPSILON) =
// Usage:
// dist = point_line_distance(line, pt, [bounded]);
// Topics: Geometry, Points, Lines, Distance
// Synopsis: Find shortest distance from point to a line, segment or ray.
// Description:
// Finds the shortest distance from the point `pt` to the specified line, segment or ray.
// The bounded parameter specifies the whether the endpoints give a ray or segment.
@ -188,8 +191,9 @@ function point_line_distance(pt, line, bounded=false) =
// dist = segment_distance(seg1, seg2, [eps]);
// Topics: Geometry, Segments, Distance
// See Also: convex_collision(), convex_distance()
// Synopsis: Find smallest distance between two line semgnets.
// Description:
// Returns the closest distance of the two given line segments.
// Returns the smallest distance of the points on two given line segments.
// Arguments:
// seg1 = The list of two points representing the first line segment to check the distance of.
// seg2 = The list of two points representing the second line segment to check the distance of.
@ -209,6 +213,7 @@ function segment_distance(seg1, seg2,eps=EPSILON) =
// Topics: Geometry, Lines
// Description:
// Returns the 2D normal vector to the given 2D line. This is otherwise known as the perpendicular vector counter-clockwise to the given ray.
// Synopsis: Return normal vector to given line.
// Arguments:
// p1 = First point on 2D line.
// p2 = Second point on 2D line.
@ -252,6 +257,7 @@ function _general_line_intersection(s1,s2,eps=EPSILON) =
// Function: line_intersection()
// Usage:
// pt = line_intersection(line1, line2, [bounded1], [bounded2], [bounded=], [eps=]);
// Synopsis: Compute intersection of two lines, segments or rays.
// Description:
// Returns the intersection point of any two 2D lines, segments or rays. Returns undef
// if they do not intersect. You specify a line by giving two distinct points on the
@ -313,6 +319,7 @@ function line_intersection(line1, line2, bounded1, bounded2, bounded, eps=EPSILO
// Usage:
// pt = line_closest_point(line, pt, [bounded]);
// Topics: Geometry, Lines, Distance
// Synopsis: Find point on given line, segment or ray that is closest to a given point.
// Description:
// Returns the point on the given line, segment or ray that is closest to the given point `pt`.
// The inputs `line` and `pt` args should be of the same dimension. The parameter bounded indicates
@ -396,9 +403,10 @@ function line_closest_point(line, pt, bounded=false) =
// Function: line_from_points()
// Usage:
// line = line_from_points(points, [fast], [eps]);
// Synopsis: Given a list of collinear points, return the line they define.
// Topics: Geometry, Lines, Points
// Description:
// Given a list of 2 or more collinear points, returns a line containing them.
// Given a list of 2 or more collinear points, returns two points defining a line containing them.
// If `fast` is false and the points are coincident or non-collinear, then `undef` is returned.
// if `fast` is true, then the collinearity test is skipped and a line passing through 2 distinct arbitrary points is returned.
// Arguments:
@ -423,6 +431,7 @@ function line_from_points(points, fast=false, eps=EPSILON) =
// Usage:
// bool = is_coplanar(points,[eps]);
// Topics: Geometry, Coplanarity
// Synopsis: Check if 3d points are coplanar and not collinear.
// Description:
// Returns true if the given 3D points are non-collinear and are on a plane.
// Arguments:
@ -444,6 +453,7 @@ function is_coplanar(points, eps=EPSILON) =
// plane = plane3pt(p1, p2, p3);
// plane = plane3pt([p1, p2, p3]);
// Topics: Geometry, Planes
// Synopsis: Return a plane from 3 points.
// Description:
// Generates the normalized cartesian equation of a plane from three 3d points.
// Returns [A,B,C,D] where Ax + By + Cz = D is the equation of a plane.
@ -467,6 +477,7 @@ function plane3pt(p1, p2, p3) =
// Usage:
// plane = plane3pt_indexed(points, i1, i2, i3);
// Topics: Geometry, Planes
// Synopsis: Given list of 3d points and 3 indices, return the plane they define.
// Description:
// Given a list of 3d points, and the indices of three of those points,
// generates the normalized cartesian equation of a plane that those points all
@ -494,6 +505,7 @@ function plane3pt_indexed(points, i1, i2, i3) =
// Function: plane_from_normal()
// Usage:
// plane = plane_from_normal(normal, [pt])
// Synopsis: Return plane defined by normal vector and a point.
// Topics: Geometry, Planes
// Description:
// Returns a plane defined by a normal vector and a point. If you omit `pt` you will get a plane
@ -554,6 +566,7 @@ function _covariance_evec_eval(points) =
// Function: plane_from_points()
// Usage:
// plane = plane_from_points(points, [fast], [eps]);
// Synopsis: Return plane defined by a set of coplanar 3d points, with arbitrary normal direction.
// Topics: Geometry, Planes, Points
// See Also: plane_from_polygon()
// Description:
@ -561,7 +574,8 @@ function _covariance_evec_eval(points) =
// that is [A,B,C,D] where Ax+By+Cz=D is the equation of the plane and norm([A,B,C])=1.
// If `fast` is false and the points in the list are collinear or not coplanar, then `undef` is returned.
// If `fast` is true, the polygon coplanarity check is skipped and a best fitting plane is returned.
// It differs from `plane_from_polygon` as the plane normal is independent of the point order. It is faster, though.
// The direction of the plane's normal is arbitrary and is not determined by the point order, unlike {{plane_from_polygon()}}.
// This function is faster than {{plane_from_polygon()}}.
// Arguments:
// points = The list of points to find the plane of.
// fast = If true, don't verify the point coplanarity. Default: false
@ -591,14 +605,17 @@ function plane_from_points(points, fast=false, eps=EPSILON) =
// Function: plane_from_polygon()
// Usage:
// plane = plane_from_polygon(points, [fast], [eps]);
// Synopsis: Given a 3d planar polygon, returns directed plane.
// Topics: Geometry, Planes, Polygons
// See Also: plane_from_points()
// Description:
// Given a 3D planar polygon, returns the normalized cartesian equation of its plane.
// Given a 3D planar polygon, returns the normalized cartesian equation of its plane.
// Returns [A,B,C,D] where Ax+By+Cz=D is the equation of the plane where norm([A,B,C])=1.
// If not all the points in the polygon are coplanar, then [] is returned.
// If `fast` is false and the points in the list are collinear or not coplanar, then `undef` is returned.
// if `fast` is true, then the coplanarity test is skipped and a plane passing through 3 non-collinear arbitrary points is returned.
// The normal direction is determined by the order of the points and the right hand rule. This is slower than {{plane_from_points()}},
// which returns an arbitrary normal.
// Arguments:
// poly = The planar 3D polygon to find the plane of.
// fast = If true, doesn't verify that all points in the polygon are coplanar. Default: false
@ -626,6 +643,7 @@ function plane_from_polygon(poly, fast=false, eps=EPSILON) =
// Usage:
// vec = plane_normal(plane);
// Topics: Geometry, Planes
// Synopsis: Returns the normal vector to a plane.
// Description:
// Returns the unit length normal vector for the given plane.
// Arguments:
@ -639,6 +657,7 @@ function plane_normal(plane) =
// Usage:
// d = plane_offset(plane);
// Topics: Geometry, Planes
// Synopsis: Returns the signed offset of the plane from the origin.
// Description:
// Returns coeficient D of the normalized plane equation `Ax+By+Cz=D`, or the scalar offset of the plane from the origin.
// This value may be negative.
@ -681,6 +700,7 @@ function _normalize_plane(plane) =
// Usage:
// pt = plane_line_intersection(plane, line, [bounded], [eps]);
// Topics: Geometry, Planes, Lines, Intersection
// Synopsis: Returns the intersection of a plane and 3d line, segment or ray.
// Description:
// Takes a line, and a plane [A,B,C,D] where the equation of that plane is `Ax+By+Cz=D`.
// If `line` intersects `plane` at one point, then that intersection point is returned.
@ -711,6 +731,7 @@ function plane_line_intersection(plane, line, bounded=false, eps=EPSILON) =
// line = plane_intersection(plane1, plane2)
// pt = plane_intersection(plane1, plane2, plane3)
// Topics: Geometry, Planes, Intersection
// Synopsis: Returns the intersection of two or three planes.
// Description:
// Compute the point which is the intersection of the three planes, or the line intersection of two planes.
// If you give three planes the intersection is returned as a point. If you give two planes the intersection
@ -745,6 +766,7 @@ function plane_intersection(plane1,plane2,plane3) =
// Usage:
// angle = plane_line_angle(plane,line);
// Topics: Geometry, Planes, Lines, Angle
// Synopsis: Returns the angle between a plane and a 3d line.
// Description:
// Compute the angle between a plane [A, B, C, D] and a 3d line, specified as a pair of 3d points [p1,p2].
// The resulting angle is signed, with the sign positive if the vector p2-p1 lies above the plane, on
@ -765,6 +787,7 @@ function plane_line_angle(plane, line) =
// Usage:
// pts = plane_closest_point(plane, points);
// Topics: Geometry, Planes, Projection
// Synopsis: Returns the orthogonal projection of points onto a plane.
// Description:
// Given a plane definition `[A,B,C,D]`, where `Ax+By+Cz=D`, and a list of 2d or
// 3d points, return the closest 3D orthogonal projection of the points on the plane.
@ -800,6 +823,7 @@ function plane_closest_point(plane, points) =
// Usage:
// dist = point_plane_distance(plane, point)
// Topics: Geometry, Planes, Distance
// Synopsis: Determine distance between a point and plane.
// Description:
// Given a plane as [A,B,C,D] where the cartesian equation for that plane
// is Ax+By+Cz=D, determines how far from that plane the given point is.
@ -831,6 +855,7 @@ function _pointlist_greatest_distance(points,plane) =
// Usage:
// bool = are_points_on_plane(points, plane, [eps]);
// Topics: Geometry, Planes, Points
// Synopsis: Determine if all of the listed points are on a plane.
// Description:
// Returns true if the given 3D points are on the given plane.
// Arguments:
@ -848,7 +873,7 @@ function are_points_on_plane(points, plane, eps=EPSILON) =
/// Usage:
/// bool = _is_point_above_plane(plane, point);
/// Topics: Geometry, Planes
// Description:
/// Description:
/// Given a plane as [A,B,C,D] where the cartesian equation for that plane
/// is Ax+By+Cz=D, determines if the given 3D point is on the side of that
/// plane that the normal points towards. The normal of the plane is the
@ -866,6 +891,7 @@ function _is_point_above_plane(plane, point) =
// Function: circle_line_intersection()
// Usage:
// pts = circle_line_intersection(r|d=, cp, line, [bounded], [eps=]);
// Synopsis: Find the intersection points between a 2d circle and a line, ray or segment.
// Topics: Geometry, Circles, Lines, Intersection
// Description:
// Find intersection points between a 2D circle and a line, ray or segment specified by two points.
@ -939,6 +965,7 @@ function _circle_or_sphere_line_intersection(r, cp, line, bounded=false, d, eps=
// Function: circle_circle_intersection()
// Usage:
// pts = circle_circle_intersection(r1|d1=, cp1, r2|d2=, cp2, [eps]);
// Synopsis: Find the intersection points of two 2d circles.
// Topics: Geometry, Circles
// Description:
// Compute the intersection points of two circles. Returns a list of the intersection points, which
@ -1007,8 +1034,9 @@ function circle_circle_intersection(r1, cp1, r2, cp2, eps=EPSILON, d1, d2) =
// circ = circle_2tangents(r|d=, pt1, pt2, pt3, [tangents=]);
// circ = circle_2tangents(r|d=, [PT1, PT2, PT3], [tangents=]);
// Topics: Geometry, Circles, Tangents
// Synopsis: Given two 2d or 3d rays, find a circle tangent to both.
// Description:
// Given a pair of rays with a common origin, and a known circle radius/diameter, finds
// Given a pair of 2d or 3d rays with a common origin, and a known circle radius/diameter, finds
// the centerpoint for the circle of that size that touches both rays tangentally.
// Both rays start at `pt2`, one passing through `pt1`, and the other through `pt3`.
// .
@ -1107,6 +1135,7 @@ function circle_2tangents(r, pt1, pt2, pt3, tangents=false, d) =
// circ = circle_3points(pt1, pt2, pt3);
// circ = circle_3points([PT1, PT2, PT3]);
// Topics: Geometry, Circles
// Synopsis: Find a circle passing through three 2d or 3d points.
// Description:
// Returns the [CENTERPOINT, RADIUS, NORMAL] of the circle that passes through three non-collinear
// points where NORMAL is the normal vector of the plane that the circle is on (UP or DOWN if the points are 2D).
@ -1157,6 +1186,7 @@ function circle_3points(pt1, pt2, pt3) =
// Usage:
// tangents = circle_point_tangents(r|d=, cp, pt);
// Topics: Geometry, Circles, Tangents
// Synopsis: Given a circle and point, find tangents to circle passing through the point.
// Description:
// Given a 2d circle and a 2d point outside that circle, finds the 2d tangent point(s) on the circle for a
// line passing through the point. Returns a list of zero or more 2D tangent points.
@ -1193,6 +1223,7 @@ function circle_point_tangents(r, cp, pt, d) =
// Usage:
// segs = circle_circle_tangents(r1|d1=, cp1, r2|d2=, cp2);
// Topics: Geometry, Circles, Tangents
// Synopsis: Find tangents to a pair of circles in 2d.
// Description:
// Computes 2d lines tangents to a pair of circles in 2d. Returns a list of line endpoints [p1,p2] where
// p1 is the tangent point on circle 1 and p2 is the tangent point on circle 2.
@ -1318,6 +1349,7 @@ function _noncollinear_triple(points,error=true,eps=EPSILON) =
// Usage:
// isect = sphere_line_intersection(r|d=, cp, line, [bounded], [eps=]);
// Topics: Geometry, Spheres, Lines, Intersection
// Synopsis: Find intersection between a sphere and line, ray or segment.
// Description:
// Find intersection points between a sphere and a line, ray or segment specified by two points.
// By default the line is unbounded.
@ -1350,6 +1382,7 @@ function sphere_line_intersection(r, cp, line, bounded=false, d, eps=EPSILON) =
// Usage:
// area = polygon_area(poly, [signed]);
// Topics: Geometry, Polygons, Area
// Synopsis: Calculate area of a 2d or 3d polygon.
// Description:
// Given a 2D or 3D simple planar polygon, returns the area of that polygon.
// If the polygon is non-planar the result is `undef.` If the polygon is self-intersecting
@ -1384,6 +1417,7 @@ function polygon_area(poly, signed=false) =
// Usage:
// c = centroid(object, [eps]);
// Topics: Geometry, Polygons, Centroid
// Synopsis: Compute centroid of a 2d or 3d polygon or a VNF.
// Description:
// Given a simple 2D polygon, returns the 2D coordinates of the polygon's centroid.
// Given a simple 3D planar polygon, returns the 3D coordinates of the polygon's centroid.
@ -1469,6 +1503,7 @@ function _polygon_centroid(poly, eps=EPSILON) =
// Usage:
// vec = polygon_normal(poly);
// Topics: Geometry, Polygons
// Synopsis: Return normal to a polygon.
// Description:
// Given a 3D simple planar polygon, returns a unit normal vector for the polygon. The vector
// is oriented so that if the normal points towards the viewer, the polygon winds in the clockwise
@ -1497,6 +1532,7 @@ function polygon_normal(poly) =
// Usage:
// bool = point_in_polygon(point, poly, [nonzero], [eps])
// Topics: Geometry, Polygons
// Synopsis: Checks if a 2d point is inside or on the boundary of a 2d polygon.
// Description:
// This function tests whether the given 2D point is inside, outside or on the boundary of
// the specified 2D polygon.
@ -1640,6 +1676,7 @@ function point_in_polygon(point, poly, nonzero=false, eps=EPSILON) =
// Usage:
// pt = polygon_line_intersection(poly, line, [bounded], [nonzero], [eps]);
// Topics: Geometry, Polygons, Lines, Intersection
// Synopsis: Find intersection between 2d or 3d polygon and a line, segment or ray.
// Description:
// Takes a possibly bounded line, and a 2D or 3D planar polygon, and finds their intersection. Note the polygon is
// treated as its boundary and interior, so the intersection may include both points and line segments.
@ -1825,6 +1862,7 @@ function _merge_segments(insegs,outsegs, eps, i=1) =
// Function: polygon_triangulate()
// Usage:
// triangles = polygon_triangulate(poly, [ind], [error], [eps])
// Synopsis: Divide a polygon into triangles.
// Description:
// Given a simple polygon in 2D or 3D, triangulates it and returns a list
// of triples indexing into the polygon vertices. When the optional argument `ind` is
@ -2015,6 +2053,7 @@ function _none_inside(idxs,poly,p0,p1,p2,eps,i=0) =
// bool = is_polygon_clockwise(poly);
// Topics: Geometry, Polygons, Clockwise
// See Also: clockwise_polygon(), ccw_polygon(), reverse_polygon()
// Synopsis: Determine if a 2d polygon winds clockwise.
// Description:
// Return true if the given 2D simple polygon is in clockwise order, false otherwise.
// Results for complex (self-intersecting) polygon are indeterminate.
@ -2040,6 +2079,7 @@ function is_polygon_clockwise(poly) =
// Usage:
// newpoly = clockwise_polygon(poly);
// Topics: Geometry, Polygons, Clockwise
// Synopsis: Return clockwise version of a polygon.
// See Also: is_polygon_clockwise(), ccw_polygon(), reverse_polygon()
// Description:
// Given a 2D polygon path, returns the clockwise winding version of that path.
@ -2053,6 +2093,7 @@ function clockwise_polygon(poly) =
// Function: ccw_polygon()
// Usage:
// newpoly = ccw_polygon(poly);
// Synopsis: Return counter-clockwise version of a polygon.
// See Also: is_polygon_clockwise(), clockwise_polygon(), reverse_polygon()
// Topics: Geometry, Polygons, Clockwise
// Description:
@ -2067,6 +2108,7 @@ function ccw_polygon(poly) =
// Function: reverse_polygon()
// Usage:
// newpoly = reverse_polygon(poly)
// Synopsis: Reverse winding direction of polygon.
// Topics: Geometry, Polygons, Clockwise
// See Also: is_polygon_clockwise(), ccw_polygon(), clockwise_polygon()
// Description:
@ -2082,6 +2124,7 @@ function reverse_polygon(poly) =
// Function: reindex_polygon()
// Usage:
// newpoly = reindex_polygon(reference, poly);
// Synopsis: Adjust point indexing of polygon to minimize pointwise distance to a reference polygon.
// Topics: Geometry, Polygons
// Description:
// Rotates and possibly reverses the point order of a 2d or 3d polygon path to optimize its pairwise point
@ -2137,13 +2180,14 @@ function reindex_polygon(reference, poly, return_error=false) =
// Usage:
// newpoly = align_polygon(reference, poly, [angles], [cp], [tran], [return_ind]);
// Topics: Geometry, Polygons
// Synopsis: Find best alignment of a 2d polygon to a reference 2d polygon over a set of transformations.
// Description:
// Find the best alignment of a specified 2D polygon with a reference 2D polygon over a set of
// transformations. You can specify a list or range of angles and a centerpoint or you can
// give a list of arbitrary 2d transformation matrices. For each transformation or angle, the polygon is
// reindexed, which is a costly operation so if run time is a problem, use a smaller sampling of angles or
// transformations. By default returns the rotated and reindexed polygon. You can also request that
// the best angle or the index into the transformation list be returned. When you specify an angle
// the best angle or the index into the transformation list be returned.
// Arguments:
// reference = reference polygon
// poly = polygon to rotate into alignment with the reference
@ -2206,6 +2250,7 @@ function align_polygon(reference, poly, angles, cp, trans, return_ind=false) =
// Description:
// Returns true if poly1 and poly2 are the same polongs
// within given epsilon tolerance.
// Synopsis: Check if two polygons (not necessarily in the same point order) are equal.
// Arguments:
// poly1 = first polygon
// poly2 = second polygon
@ -2258,6 +2303,7 @@ function ___is_polygon_in_list(poly, polys, i) =
// Function: hull()
// Usage:
// face_list_or_index_list = hull(points);
// Synopsis: Convex hull of a list of 2d or 3d points.
// Description:
// Takes a list of 2D or 3D points (but not both in the same list) and returns either the list of
// indexes into `points` that forms the 2D convex hull perimeter path, or the list of faces that
@ -2278,6 +2324,7 @@ function hull(points) =
// Module: hull_points()
// Usage:
// hull_points(points, [fast]);
// Synopsis: Convex hull of a list of 2d or 3d points.
// Description:
// If given a list of 2D points, creates a 2D convex hull polygon that encloses all those points.
// If given a list of 3D points, creates a 3D polyhedron that encloses all the points. This should
@ -2339,6 +2386,7 @@ function _is_cw(a,b,c,all) =
// Takes a list of arbitrary 2D points, and finds the convex hull polygon to enclose them.
// Returns a path as a list of indices into `points`.
// When all==true, returns extra points that are on edges of the hull.
// Synopsis: Convex hull of a list of 2d points.
// Arguments:
// points = list of 2d points to get the hull of.
// all = when true, includes all points on the edges of the convex hull. Default: false.
@ -2397,6 +2445,7 @@ function _hull_collinear(points) =
// Function: hull3d_faces()
// Usage:
// faces = hull3d_faces(points)
// Synopsis: Convex hull of a list of 3d points.
// Description:
// Takes a list of arbitrary 3D points, and finds the convex hull polyhedron to enclose
// them. Returns a list of triangular faces, where each face is a list of indexes into the given `points`
@ -2508,6 +2557,7 @@ function _find_first_noncoplanar(plane, points, i=0) =
// Function: is_polygon_convex()
// Usage:
// bool = is_polygon_convex(poly, [eps]);
// Synopsis: Check if a polygon is convex.
// Topics: Geometry, Convexity, Test
// Description:
// Returns true if the given 2D or 3D polygon is convex.
@ -2553,6 +2603,7 @@ function is_polygon_convex(poly,eps=EPSILON) =
// Function: convex_distance()
// Usage:
// dist = convex_distance(points1, points2,eps);
// Synopsis: Compute distance between convex hull of two point lists.
// Topics: Geometry, Convexity, Distance
// See also:
// convex_collision(), hull()
@ -2615,8 +2666,9 @@ function _GJK_distance(points1, points2, eps=EPSILON, lbd, d, simplex=[]) =
// Topics: Geometry, Convexity, Collision, Intersection
// See also:
// convex_distance(), hull()
// Synopsis: Check whether the convex hulls of two point lists intersect.
// Description:
// Returns `true` if the convex hull of `points1` intercepts the convex hull of `points2`
// Returns `true` if the convex hull of `points1` intersects the convex hull of `points2`
// otherwise, `false`.
// All the points in the lists should have the same dimension, either 2D or 3D.
// This function is tipically faster than `convex_distance` to find a non-collision.
@ -2762,6 +2814,7 @@ function _support_diff(p1,p2,d) =
// Function: rot_decode()
// Usage:
// info = rot_decode(rotation,[long]); // Returns: [angle,axis,cp,translation]
// Synopsis: Extract axis and rotation angle from a rotation matrix.
// Topics: Affine, Matrices, Transforms
// Description:
// Given an input 3D rigid transformation operator (one composed of just rotations and translations) represented

View file

@ -2912,7 +2912,7 @@ function onion(r, ang=45, cap_h, d, anchor=CENTER, spin=0, orient=UP) =
// text3d("Fogmobar", h=2, anchor=CENTER, atype="ycenter");
// text3d("Fogmobar", h=2, anchor=RIGHT);
// text3d("Fogmobar", h=2, anchor=RIGHT+BOT, atype="ycenter");
module text3d(text, h, size=10, font="Helvetica", spacing=1.0, direction="ltr", language="em", script="latin",
module text3d(text, h, size=10, font="Helvetica", spacing=1.0, direction="ltr", language="en", script="latin",
height, thickness, atype, center=false,
anchor, spin=0, orient=UP) {
no_children($children);