## geometry2d.api
#
# The api of the basic geometry types and operations.
# Compiled by:
#
src/lib/std/standard.lib### "Life without geometry is pointless."
### "Let no one ignorant of Geometry enter here." -- Pythagoras
# This api is implemented in:
#
#
src/lib/std/2d/geometry2d.pkg# Used in:
#
src/lib/x-kit/draw/band.pkg#
src/lib/x-kit/draw/scan-convert.pkgapi Geometry2d {
# Geometric types (from Xlib::h)
#
Point = { row: Int,
col: Int
};
Line = (Point, Point);
Size = { wide: Int,
high: Int
};
# Screen rectangles represented as
# upper-left corner plus size.
#
# For two-corner box representation see
#
src/lib/x-kit/draw/box2.pkg #
Box = { row: Int,
col: Int,
wide: Int,
high: Int
};
Arc = { row: Int,
col: Int,
wide: Int,
high: Int,
start_angle: Float, # In degrees, with zero angle at 3 o'clock, increasing counterclockwise. Use positive angles from 0.0 to 360.0.
fill_angle: Float # Draw a pie-slice of this many degrees starting at start_angle and running counterclockwise from there.
};
# Examples:
# Upper-right quadrant == { ..., start_angle => 0.0, fill_angle => 90.0 }
# Upper-left quadrant == { ..., start_angle => 90.0, fill_angle => 90.0 }
# Lower-left quadrant == { ..., start_angle => 180.0, fill_angle => 90.0 }
# Lower-right quadrant == { ..., start_angle => 270.0, fill_angle => 90.0 }
# Upper half == { ... start_angle => 0.0, fill_angle => 180.0 };
# Lower half == { ... start_angle => 180.0, fill_angle => 180.0 };
# Full disk == { ..., start_angle => 0.0, fill_angle => 360.0 }
Arc64 = { row: Int,
col: Int,
#
wide: Int,
high: Int,
#
angle1: Int, # In degrees * 64, with zero angle at 3 o'clock, increasing counterclockwise.
angle2: Int # In degrees * 64. Arc is drawn from angle1 for angle2 degrees.
};
# The size and position of a window
# relative to its parent.
#
# Note that position does not take
# border_thickness into account.
#
Window_Site
=
{
upperleft: Point,
size: Size,
border_thickness: Int # In pixels.
};
# Points:
#
package point: api {
#
zero: Point; # Point (0,0).
row: Point -> Int;
col: Point -> Int;
scale: (Point, Int ) -> Point;
add: (Point, Point) -> Point;
subtract: (Point, Point) -> Point;
add_size: (Point, Size ) -> Point;
clip: (Point, Size ) -> Point; # Clip point to be within box defined by point::zero and size, using orthogonal projection..
ne: (Point, Point) -> Bool; # x1 != x2 or y1 != y2.
eq: (Point, Point) -> Bool; # x1 == x2 and y1 == y2.
lt: (Point, Point) -> Bool; # x1 < x2 and y1 < y2.
le: (Point, Point) -> Bool; # x1 <= x2 and y1 <= y2
gt: (Point, Point) -> Bool; # x1 > x2 and y1 > y2
ge: (Point, Point) -> Bool; # x1 >= x2 and y1 >= y2
in_box: (Point, Box ) -> Bool; # TRUE iff point is within box.
compare_xy: (Point, Point) -> Order; # Comparison fn to sort points by X (and by Y when X coords match).
# Used in convex_hull; generally useful when a total order is needed, e.g.:
#
# points = list_mergesort::sort_list_and_drop_duplicates point::compare_xy points;
mean: List(Point) -> Point;
};
package size: api {
#
add: (Size, Size) -> Size;
subtract: (Size, Size) -> Size;
scale: (Size, Int ) -> Size;
eq: (Size, Size) -> Bool;
};
#
package box: api {
#
zero: Box; # Box (0,0,0,0).
ne: (Box, Box) -> Bool;
eq: (Box, Box) -> Bool;
make: (Point, Size) -> Box;
upperleft: Box -> Point;
lowerright: Box -> Point; # Returns { col => box.col + box.wide - 1, row => box.row + box.high - 1 }
lowerright1: Box -> Point; # Returns { col => box.col + box.wide , row => box.row + box.high }
size: Box -> Size;
area: Box -> Int;
midpoint: Box -> Point;
to_points: Box -> List(Point);
box_corners: Box -> { upper_left: Point,
lower_left: Point,
lower_right: Point,
upper_right: Point
};
upperleft_and_size: Box -> (Point, Size);
clip_point: (Box, Point) -> Point; # Clip point to be within box, using orthogonal projection.
translate: (Box, Point) -> Box; # box.upperleft += point.
rtranslate: (Box, Point) -> Box; # box.upperleft -= point.
intersect: (Box, Box) -> Bool; # TRUE iff the boxes overlap.
intersection: (Box, Box) -> Null_Or(Box); # Construct largest box contained by both input boxes. Return NULL if they don't overlap.
union: (Box, Box) -> Box; # Construct smallest box containing both input boxes.
xor: (Box, Box) -> List(Box); # Construct the symmetric difference of two boxes.
point_in_box: (Point, Box) -> Bool; # TRUE iff point is within box: (box.row <= point.row < box.row + box.high) and (box.col <= point.col < box.col + box.wide).
box_a_in_box_b: { a: Box, b: Box } -> Bool; # TRUE iff first box is within second.
point_on_box_perimeter: (Point, Box) -> Bool; #
make_nested_box:(Box, Int) -> Box; # Create a box nested within given box, shrunk by given number of pixels.
# Returns given box unchanged if given box is <= 2 pixels high or wide.
# Returns given box unchanged if shrink distance is <= 0.
intersect_box_with_boxes: (Box, List(Box)) -> List(Box);
intersect_boxes_with_boxes: (List(Box), List(Box)) -> List(Box);
quadsect_box: (Box, Point) -> List(Box); # Split a box into subboxes such that none cross the horizontal or vertical line running through the given point.
quadsect_boxes: (List(Box), Point) -> List(Box);
subtract_box_b_from_box_a: { a: Box, b: Box } -> List(Box); # Split 'a' into sub-boxes which do not cross the edges of 'b', then remove all sub-boxes which are contained in 'b' and return the rest.
subtract_boxes_b_from_boxes_a: { a: List(Box), b: List(Box) } -> List(Box); # As above, but subtracting box-set b from box-set a. We don't try to be smart, just simple -- this is intended for small-scale problems.
};
package line: api {
#
intersection # Find the intersection of two lines. Return NULL if the lines are parallel.
:
(Line, Line) -> Null_Or(Point);
rotate_90_degrees_counterclockwise # Rotate given line segment by a right angle around first point. Result line has same first point as given line.
:
Line -> Line;
};
bounding_box: List(Point) -> Box; # Construct bounding box for given points.
# Empty list returns BOX { col=>0, row=>0, wide=>0, high=>0 };
convex_hull: List(Point) -> List(Point); # http://en.wikibooks.org/wiki/Algorithm_Implementation/Geometry/Convex_hull/Monotone_chain
point_in_polygon
:
(Point, List(Point)) -> Bool;
};
## COPYRIGHT (c) 1990, 1991 by John H. Reppy. See SMLNJ-COPYRIGHT file for details.
## Subsequent changes by Jeff Prothero Copyright (c) 2010-2015,
## released per terms of SMLNJ-COPYRIGHT.