Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Geometric Analysis

Part 2 concludes with advanced analysis. You can inspect the geometry you create to verify angles, measure distances, or optimize performance.

The Stone Variable

The Stone variable is a built-in structure that updates automatically whenever you use := with geometry.

// Setup
_ := Cube(2)

// Accessing Stone properties
_ := "Volume: " + Stone.volume
_ := "Area: " + Stone.area
_ := "Center: " + Stone.center

It also contains arrays of the raw geometry:

  • Stone.planes: All planes added.
  • Stone.vertices: Calculated convex hull vertices.

Filtering Facets

You can use the functional skills from Part 1 to inspect specific parts of the stone.

Example: Counting Facets by Type

// Setup
_ := Cube(2)

// Helper to classify facets
is_pavilion = (p) => p.normal.z < -0.01
is_crown    = (p) => p.normal.z > 0.01
is_girdle   = (p) => abs(p.normal.z) <= 0.01

// Filter the Stone.planes array
pav_count = (Stone.planes ?| is_pavilion).length
crown_count = (Stone.planes ?| is_crown).length

_ := "Pavilion Facets: " + pav_count
_ := "Crown Facets: " + crown_count

Ray Casting

You can "shoot" a laser through the stone to measure thickness or light paths.

Operator: Line * Stone -> Returns sorted array of intersection points.

Example: Measuring Center Thickness

// Setup
_ := Cube(2)

// 1. Define a Ray straight down through the center
ray = Line(Point(0,0,10), Vector(0,0,-1))

// 2. Cast against the Stone
hits := ray * Stone

// 3. Analyze
// hits[0] is entry (Table), hits[1] is exit (Culet)
thickness = hits[0] ^ hits[1]

_ := "Center Thickness: " + thickness

Custom Analysis Tools

You can build your own tools using Blocks and Lambdas.

Example: Bounding Box

// Setup
_ := Cube(2)

BoundingBox = (points) => {
    {
        min: Point(
            min(points |> (p) => p.x),
            min(points |> (p) => p.y),
            min(points |> (p) => p.z)
        ),
        max: Point(
            max(points |> (p) => p.x),
            max(points |> (p) => p.y),
            max(points |> (p) => p.z)
        )
    }
}

// Usage
box = BoundingBox(Stone.vertices)
_ := "Height: " + (box.max.z - box.min.z)