Smith.Plane (Smith v0.1.0)

Copy Markdown View Source

A local, right-handed coordinate frame for sketches and holes.

A plane consists of an origin, two in-plane unit axes, and a unit normal. Sketch coordinates {u, v} are measured along those local axes. Positive sketch extrusion follows the normal.

ConstructorLocal XLocal YNormal
xy/1+X+Y+Z
yz/1+Y+Z+X
xz/1+X+Z−Y

Constructors return deferred values. to_world/2, normal/1, or model evaluation validates the definition. A plane does not select or attach to a model face: moving a body does not move its plane. See sketches and planes for placement examples.

Summary

Functions

Defines a plane from a world origin and two direction vectors.

Returns the plane's normalized world normal as a tagged result.

Converts a local {u, v} point into world coordinates.

Defines an XY plane with local X=world +X, local Y=world +Y, and normal +Z.

Defines an XZ plane with local X=world +X, local Y=world +Z, and normal −Y.

Defines a YZ plane with local X=world +Y, local Y=world +Z, and normal +X.

Types

t()

@type t() :: %Smith.Plane{kind: atom(), options: keyword()}

Functions

new(opts \\ [])

@spec new(keyword()) :: t()

Defines a plane from a world origin and two direction vectors.

Options default to origin: {0, 0, 0}, normal: {0, 0, 1}, and x_direction: {1, 0, 0}. At evaluation, the normal is normalized and :x_direction is projected into the plane, then normalized. Local Y is the cross product of the normal and local X.

Both the normal and projected X must have magnitude greater than 1.0e-12. A zero normal or parallel X direction returns :invalid_plane when queried or evaluated. Supply another X direction when the default is parallel to your chosen normal. Unknown or duplicate options also fail.

normal(plane)

@spec normal(t()) :: {:ok, {float(), float(), float()}} | {:error, atom()}

Returns the plane's normalized world normal as a tagged result.

Validates the whole frame, including its X direction. Invalid frames return {:error, :invalid_plane}. This is an Elixir calculation and does not allocate a native shape.

to_world(plane, arg2)

@spec to_world(t(), {number(), number()}) ::
  {:ok, {float(), float(), float()}} | {:error, atom()}

Converts a local {u, v} point into world coordinates.

Returns {:ok, {x, y, z}} after validating the frame. Invalid local point arguments return :invalid_point; invalid plane definitions return :invalid_plane. This query performs Elixir arithmetic, without a native geometry call.

xy(opts \\ [])

@spec xy(keyword()) :: t()

Defines an XY plane with local X=world +X, local Y=world +Y, and normal +Z.

Accepts z: (default 0) or origin: {x, y, z}, but not both. The :z option sets the world Z coordinate, with X=Y=0.

iex> Smith.Plane.xy(z: 5) |> Smith.Plane.to_world({2, 3})
{:ok, {2.0, 3.0, 5.0}}

xz(opts \\ [])

@spec xz(keyword()) :: t()

Defines an XZ plane with local X=world +X, local Y=world +Z, and normal −Y.

Accepts y: (default 0) or origin: {x, y, z}, but not both. :y sets the world Y coordinate, not a signed offset along the normal. A positive sketch extrusion therefore moves toward decreasing world Y.

iex> Smith.Plane.xz(y: 10) |> Smith.Plane.to_world({2, 3})
{:ok, {2.0, 10.0, 3.0}}
iex> Smith.Plane.xz() |> Smith.Plane.normal()
{:ok, {0.0, -1.0, 0.0}}

yz(opts \\ [])

@spec yz(keyword()) :: t()

Defines a YZ plane with local X=world +Y, local Y=world +Z, and normal +X.

Accepts x: (default 0) or origin: {x, y, z}, but not both. The :x option sets the world X coordinate, with Y=Z=0.

iex> Smith.Plane.yz(x: 10) |> Smith.Plane.to_world({2, 3})
{:ok, {10.0, 2.0, 3.0}}