Files
modeling-app/docs/kcl/patternTransform.md
Jess Frazelle 790af3842c Recusive docs (#4023)
updates



updates



updates



updates



updates



updates



better



updates



array of



updates



updates



updates



updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>
2024-09-27 19:50:44 -07:00

676 KiB

title, excerpt, layout
title excerpt layout
patternTransform Repeat a 3-dimensional solid, changing it each time. manual

Repeat a 3-dimensional solid, changing it each time.

Replicates the 3D solid, applying a transformation function to each replica. Transformation function could alter rotation, scale, visibility, position, etc. The `patternTransform` call itself takes a number for how many total instances of the shape should be. For example, if you use a circle with `patternTransform(4, transform)` then there will be 4 circles: the original, and 3 created by replicating the original and calling the transform function on each. The transform function takes a single parameter: an integer representing which number replication the transform is for. E.g. the first replica to be transformed will be passed the argument `1`. This simplifies your math: the transform function can rely on id `0` being the original instance passed into the `patternTransform`. See the examples.

patternTransform(total_instances: u32, transform_function: FunctionParam, solid_set: SolidSet) -> [Solid]

Arguments

Name Type Description Required
total_instances u32 Yes
transform_function FunctionParam Yes
solid_set SolidSet A solid or a group of solids. Yes

Returns

[Solid]

Examples

// Each instance will be shifted along the X axis.
fn transform = (id) => {
  return { translate: [4 * id, 0, 0] }
}

// Sketch 4 cylinders.
const sketch001 = startSketchOn('XZ')
  |> circle({ center: [0, 0], radius: 2 }, %)
  |> extrude(5, %)
  |> patternTransform(4, transform, %)

Rendered example of patternTransform 0

// Each instance will be shifted along the X axis,
// with a gap between the original (at x = 0) and the first replica
// (at x = 8). This is because `id` starts at 1.
fn transform = (id) => {
  return { translate: [4 * (1 + id), 0, 0] }
}

const sketch001 = startSketchOn('XZ')
  |> circle({ center: [0, 0], radius: 2 }, %)
  |> extrude(5, %)
  |> patternTransform(4, transform, %)

Rendered example of patternTransform 1

fn cube = (length, center) => {
  let l = length / 2
  let x = center[0]
  let y = center[1]
  let p0 = [-l + x, -l + y]
  let p1 = [-l + x, l + y]
  let p2 = [l + x, l + y]
  let p3 = [l + x, -l + y]

  return startSketchAt(p0)
  |> lineTo(p1, %)
  |> lineTo(p2, %)
  |> lineTo(p3, %)
  |> lineTo(p0, %)
  |> close(%)
  |> extrude(length, %)
}

let width = 20
fn transform = (i) => {
  return {
  // Move down each time.
  translate: [0, 0, -i * width],
  // Make the cube longer, wider and flatter each time.
  scale: [pow(1.1, i), pow(1.1, i), pow(0.9, i)],
  // Turn by 15 degrees each time.
  rotation: { angle: 15 * i, origin: "local" }
}
}

let myCubes = cube(width, [100, 0])
  |> patternTransform(25, transform, %)

Rendered example of patternTransform 2

fn cube = (length, center) => {
  let l = length / 2
  let x = center[0]
  let y = center[1]
  let p0 = [-l + x, -l + y]
  let p1 = [-l + x, l + y]
  let p2 = [l + x, l + y]
  let p3 = [l + x, -l + y]

  return startSketchAt(p0)
  |> lineTo(p1, %)
  |> lineTo(p2, %)
  |> lineTo(p3, %)
  |> lineTo(p0, %)
  |> close(%)
  |> extrude(length, %)
}

let width = 20
fn transform = (i) => {
  return {
  translate: [0, 0, -i * width],
  rotation: {
    angle: 90 * i,
    // Rotate around the overall scene's origin.
    origin: "global"
  }
}
}
let myCubes = cube(width, [100, 100])
  |> patternTransform(4, transform, %)

Rendered example of patternTransform 3

// Parameters
const r = 50 // base radius
const h = 10 // layer height
const t = 0.005 // taper factor [0-1)
// Defines how to modify each layer of the vase.
// Each replica is shifted up the Z axis, and has a smoothly-varying radius
fn transform = (replicaId) => {
  let scale = r * abs(1 - (t * replicaId)) * (5 + cos(replicaId / 8))
  return {
  translate: [0, 0, replicaId * 10],
  scale: [scale, scale, 0]
}
}
// Each layer is just a pretty thin cylinder.
fn layer = () => {
  return startSketchOn("XY")
  // or some other plane idk
  |> circle({ center: [0, 0], radius: 1 }, %, $tag1)
  |> extrude(h, %)
}
// The vase is 100 layers tall.
// The 100 layers are replica of each other, with a slight transformation applied to each.
let vase = layer()
  |> patternTransform(100, transform, %)

Rendered example of patternTransform 4