updates updates updates updates updates updates better updates array of updates updates updates updates Signed-off-by: Jess Frazelle <github@jessfraz.com>
167 lines
676 KiB
Markdown
167 lines
676 KiB
Markdown
---
|
|
title: "patternTransform"
|
|
excerpt: "Repeat a 3-dimensional solid, changing it each time."
|
|
layout: 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.
|
|
|
|
```js
|
|
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`](/docs/kcl/types/SolidSet) | A solid or a group of solids. | Yes |
|
|
|
|
### Returns
|
|
|
|
[`[Solid]`](/docs/kcl/types/Solid)
|
|
|
|
|
|
### Examples
|
|
|
|
```js
|
|
// 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, %)
|
|
```
|
|
|
|

|
|
|
|
```js
|
|
// 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, %)
|
|
```
|
|
|
|

|
|
|
|
```js
|
|
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, %)
|
|
```
|
|
|
|

|
|
|
|
```js
|
|
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, %)
|
|
```
|
|
|
|

|
|
|
|
```js
|
|
// 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, %)
|
|
```
|
|
|
|

|
|
|
|
|