Files
modeling-app/src/lib/rectangleTool.ts

113 lines
3.3 KiB
TypeScript
Raw Normal View History

import {
createArrayExpression,
createBinaryExpression,
createCallExpressionStdLib,
createLiteral,
createPipeSubstitution,
createUnaryExpression,
} from 'lang/modifyAst'
import { roundOff } from './utils'
import { ArrayExpression, CallExpression, PipeExpression } from 'lang/wasm'
/**
* Returns AST expressions for this KCL code:
* const yo = startSketchOn('XY')
* |> startProfileAt([0, 0], %)
* |> angledLine([0, 0], %, 'a')
* |> angledLine([segAng('a', %) - 90, 0], %, 'b')
* |> angledLine([segAng('a', %), -segLen('a', %)], %, 'c')
* |> close(%)
*/
export const getRectangleCallExpressions = (
rectangleOrigin: [number, number],
tags: [string, string, string]
) => [
createCallExpressionStdLib('startProfileAt', [
createArrayExpression([
createLiteral(roundOff(rectangleOrigin[0])),
createLiteral(roundOff(rectangleOrigin[1])),
]),
createPipeSubstitution(),
]),
createCallExpressionStdLib('angledLine', [
createArrayExpression([
createLiteral(0), // 0 deg
createLiteral(0), // This will be the width of the rectangle
]),
createPipeSubstitution(),
createLiteral(tags[0]),
]),
createCallExpressionStdLib('angledLine', [
createArrayExpression([
createBinaryExpression([
createCallExpressionStdLib('segAng', [
createLiteral(tags[0]),
createPipeSubstitution(),
]),
'+',
createLiteral(90),
]), // 90 offset from the previous line
createLiteral(0), // This will be the height of the rectangle
]),
createPipeSubstitution(),
createLiteral(tags[1]),
]),
createCallExpressionStdLib('angledLine', [
createArrayExpression([
createCallExpressionStdLib('segAng', [
createLiteral(tags[0]),
createPipeSubstitution(),
]), // same angle as the first line
createUnaryExpression(
createCallExpressionStdLib('segLen', [
createLiteral(tags[0]),
createPipeSubstitution(),
]),
'-'
), // negative height
]),
createPipeSubstitution(),
createLiteral(tags[2]),
]),
createCallExpressionStdLib('lineTo', [
createArrayExpression([
createCallExpressionStdLib('profileStartX', [createPipeSubstitution()]),
createCallExpressionStdLib('profileStartY', [createPipeSubstitution()]),
]),
createPipeSubstitution(),
]), // close the rectangle
createCallExpressionStdLib('close', [createPipeSubstitution()]),
]
/**
* Mutates the pipeExpression to update the rectangle sketch
* @param pipeExpression
* @param x
* @param y
* @param tag
*/
export function updateRectangleSketch(
pipeExpression: PipeExpression,
x: number,
y: number,
tag: string
) {
;((pipeExpression.body[2] as CallExpression)
.arguments[0] as ArrayExpression) = createArrayExpression([
createLiteral(x >= 0 ? 0 : 180),
createLiteral(Math.abs(x)),
])
;((pipeExpression.body[3] as CallExpression)
.arguments[0] as ArrayExpression) = createArrayExpression([
createBinaryExpression([
createCallExpressionStdLib('segAng', [
createLiteral(tag),
createPipeSubstitution(),
]),
Math.sign(y) === Math.sign(x) ? '+' : '-',
createLiteral(90),
]), // 90 offset from the previous line
createLiteral(Math.abs(y)), // This will be the height of the rectangle
])
}