Yichus/Geometry
Builtin package (resource geometry.bosatsu).
This is the complete package source used by this build. The export
list names its public API; definitions below give the types and behavior.
New to the API? Start with Make a calculator or Build an API, then use this page to look up a definition.
package Yichus/Geometry from Yichus/Num/Float64 import ( Float64, addf, subf, mulf, divf, abs_Float64, int_to_Float64 ) export ( Line(), Point(), intersect, shift, y_at, horizontal, triangle_area, trapezoid_area, area_between ) exposes (Yichus/Num/Float64) # Closed-form Euclidean helpers for calculator graphs. # A Line is P = intercept + slope * q. Intersections and areas are # ordinary Bosatsu bindings, so Why/Math explore them like any other value. struct Line(slope: Float64, intercept: Float64) struct Point(x: Float64, y: Float64) def zero() -> Float64: int_to_Float64(0) def half() -> Float64: divf(int_to_Float64(1), int_to_Float64(2)) def y_at(line: Line, x: Float64) -> Float64: Line(slope, intercept) = line addf(intercept, mulf(slope, x)) def shift(line: Line, dy: Float64) -> Line: Line(slope, intercept) = line Line(slope, addf(intercept, dy)) def horizontal(y: Float64) -> Line: Line(zero(), y) # q = (b0 - a0) / (a1 - b1) so a0 + a1*q = b0 + b1*q. # Parallel lines have no unique crossing: the division is by zero and the # result is IEEE infinity/NaN, never a fabricated finite point. The graph # runtime surfaces non-finite marks visibly instead of drawing them. def intersect(a: Line, b: Line) -> Point: Line(a1, a0) = a Line(b1, b0) = b q = divf(subf(b0, a0), subf(a1, b1)) Point(q, y_at(a, q)) def triangle_area(p1: Point, p2: Point, p3: Point) -> Float64: Point(x1, y1) = p1 Point(x2, y2) = p2 Point(x3, y3) = p3 term1 = mulf(x1, subf(y2, y3)) term2 = mulf(x2, subf(y3, y1)) term3 = mulf(x3, subf(y1, y2)) mulf(half(), abs_Float64(addf(term1, addf(term2, term3)))) # Area of the trapezoid between two y-pairs over [x0, x1]. # Sign follows (upper - lower); callers that want magnitude use abs. def trapezoid_area( x0: Float64, x1: Float64, y_upper_0: Float64, y_upper_1: Float64, y_lower_0: Float64, y_lower_1: Float64 ) -> Float64: width = subf(x1, x0) left = subf(y_upper_0, y_lower_0) right = subf(y_upper_1, y_lower_1) mulf(width, mulf(half(), addf(left, right))) def area_between(upper: Line, lower: Line, x0: Float64, x1: Float64) -> Float64: y_u0 = y_at(upper, x0) y_u1 = y_at(upper, x1) y_l0 = y_at(lower, x0) y_l1 = y_at(lower, x1) abs_Float64(trapezoid_area(x0, x1, y_u0, y_u1, y_l0, y_l1))