Skip to main content

Custom Dimensions

In case you want to build your own dimensions that don't really fit the style of the standard ones, here are some functions to generate custom dimensions to your layouts that you can use as a template and change it according to your needs:

A. Coordinate

function addCoordinateDimension(
layout: SKYCAD.Layout,
position: SKYMATH.Vector2D,
{ textSize = 30, decimals = 1 } = {},
) {
const crossSize = 0.75 * textSize
const crossSketch = new SKYCAD.Sketch()
crossSketch.moveTo(-0.5 * crossSize, 0)
crossSketch.lineTo(0.5 * crossSize, 0)
crossSketch.moveTo(0, -0.5 * crossSize)
crossSketch.lineTo(0, 0.5 * crossSize)
layout.addSketch(crossSketch, { position })

layout.addText(`(${position.x.toFixed(decimals)},${position.y.toFixed(decimals)})`, {
size: textSize,
position: SKYMATH.add(position, new SKYMATH.Vector2D(0, -1.5 * textSize)),
align: 'center',
})
}
  • Example of use:
const layout = new SKYCAD.Layout()
const P1 = new SKYMATH.Vector2D(200, 150)
addCoordinateDimension(layout, P1, { textSize: 25, decimals: 2 })

B. Label

function addLabelDimension(
layout: SKYCAD.Layout,
radius: number,
{
textSize = 25,
position = new SKYMATH.Vector2D(0, 0),
decimals = 1,
align = { vertical: 'top', horizontal: 'right' } as {
vertical: 'top' | 'bottom'
horizontal: 'left' | 'right'
},
} = {},
) {
const isBottomAligned = align.vertical === 'bottom'
const isLeftAligned = align.horizontal === 'left'
const text = `R${radius.toFixed(decimals)}`

// arrow
const arrowSketch = new SKYCAD.Sketch()

// --- body
const arrowAngle = (45 * Math.PI) / 180

const v12 = new SKYMATH.Vector2D(1.5 * textSize, 0)
v12.rotate(arrowAngle)
const v23 = new SKYMATH.Vector2D(SKYCAD.getTextWidth(text, textSize), 0)

const P0 = new SKYMATH.Vector2D(0, 0)
const P1 = SKYMATH.add(P0, v12)
const P2 = SKYMATH.add(P1, v23)

arrowSketch.moveTo(P0)
arrowSketch.lineTo(P1)
arrowSketch.lineTo(P2)

// --- head
arrowSketch.moveTo(P0)
const v1a = new SKYMATH.Vector2D(0.5 * textSize, 0)
v1a.rotate(arrowAngle + (20 * Math.PI) / 180)
arrowSketch.lineTo(SKYMATH.add(P0, v1a))

arrowSketch.moveTo(P0)
const v1b = new SKYMATH.Vector2D(0.5 * textSize, 0)
v1b.rotate(arrowAngle - (20 * Math.PI) / 180)
arrowSketch.lineTo(SKYMATH.add(P0, v1b))

if (isBottomAligned) arrowSketch.mirrorInXaxis()
if (isLeftAligned) arrowSketch.mirrorInYaxis()

layout.addSketch(arrowSketch, { position })

const node1 = arrowSketch.getNodes()[1]! // P1 translated

const textPosition = SKYMATH.add(node1, new SKYMATH.Vector2D(0, 0.1 * textSize))

// text
layout.addText(text, {
align: isLeftAligned ? 'right' : 'left',
position: SKYMATH.add(position, textPosition),
size: textSize,
})
}
  • Example of use:
const layout = new SKYCAD.Layout()
const radius = 25
const positionAtCircleContour = new SKYMATH.Vector2D(radius * Math.cos(Math.PI / 4), radius * Math.sin(Math.PI / 4))
addLabelDimension(layout, radius, {
textSize: 20,
decimals: 0,
align: { vertical: 'top', horizontal: 'right' },
position: positionAtCircleContour,
})

C. Radial

function addRadialDimension(
layout: SKYCAD.Layout,
radius: number,
{
rotation = (30 * Math.PI) / 180, // [45 deg in rad]
textSize = 25,
position = new SKYMATH.Vector2D(0, 0),
decimals = 1,
} = {},
) {
const text = `R${radius.toFixed(decimals)}`
const textWidth = SKYCAD.getTextWidth(text, textSize)

// arrow
// --- body
const arrowSketch = new SKYCAD.Sketch()
arrowSketch.moveTo(0, 0)
arrowSketch.lineTo(radius + textWidth, 0)

// --- head
arrowSketch.moveTo(radius - 0.3 * textSize, 0.1 * textSize)
arrowSketch.lineTo(radius, 0)
arrowSketch.lineTo(radius - 0.3 * textSize, -0.1 * textSize)

layout.addSketch(arrowSketch, { position, rotation })

// text
let textPosition = new SKYMATH.Vector2D(radius, 0.1 * textSize)
let textRotation = rotation
const isTextUpsideDown = Math.sign(Math.cos(rotation)) === -1
if (isTextUpsideDown) {
textPosition = new SKYMATH.Vector2D(-radius - textWidth, 0.1 * textSize)
textPosition.rotate(rotation - Math.PI)
textRotation = rotation - Math.PI
} else {
textPosition.rotate(rotation)
}
layout.addText(text, {
position: SKYMATH.add(position, textPosition),
rotation: textRotation,
size: textSize,
})
}
  • Example of use:
const layout = new SKYCAD.Layout()
const radius = 25
addRadialDimension(layout, radius, {
rotation: (30 * Math.PI) / 180, // [rad]
textSize: 20,
decimals: 0,
// position: new SKYMATH.Vector2D(250, 300),
})

D. Arrow

function addArrowDimension(
layout: SKYCAD.Layout,
value: number,
{
rotation = (30 * Math.PI) / 180, // [45 deg in rad]
textSize = 25,
position = new SKYMATH.Vector2D(0, 0),
decimals = 1,
} = {},
) {
const text = `${value.toFixed(decimals)}`
const textWidth = SKYCAD.getTextWidth(text, textSize)

// arrow
// --- body
const arrowLength = 2 * textSize
const arrowSketch = new SKYCAD.Sketch()
arrowSketch.moveTo(0, 0)
arrowSketch.lineTo(arrowLength, 0)

// --- head
arrowSketch.moveTo(arrowLength - 0.5 * textSize, 0.2 * textSize)
arrowSketch.lineTo(arrowLength, 0)
arrowSketch.lineTo(arrowLength - 0.5 * textSize, -0.2 * textSize)

layout.addSketch(arrowSketch, { position, rotation })

// text
let textPosition = new SKYMATH.Vector2D(arrowLength, -0.33 * textSize)
let textRotation = rotation
const isTextUpsideDown = Math.sign(Math.cos(rotation)) === -1
if (isTextUpsideDown) {
textPosition = new SKYMATH.Vector2D(-arrowLength - textWidth, -0.33 * textSize)
textPosition.rotate(rotation - Math.PI)
textRotation = rotation - Math.PI
} else {
textPosition.rotate(rotation)
}
layout.addText(text, {
position: SKYMATH.add(position, textPosition),
rotation: textRotation,
size: textSize,
})
}
  • Example of use:
const layout = new SKYCAD.Layout()
const radius = 25
addArrowDimension(layout, radius, {
textSize: 20,
decimals: 0,
// position: new SKYMATH.Vector2D(250, 300),
})

E. Linear

function addLinearDimension(layout: SKYCAD.Layout, values: number[], { textSize = 5, decimals = 1, offset = 50 } = {}) {
const originSketch = SKYCAD.generateCircleSketch(0, 0, 0.1 * textSize)
layout.addSketch(originSketch, {
position: new SKYMATH.Vector2D(0, -offset),
fillColor: 0x000000,
})

const minValue = Math.min(...values)
const maxValue = Math.max(...values)

const lineSketch = new SKYCAD.Sketch()
lineSketch.moveTo(minValue, 0)
lineSketch.lineTo(maxValue, 0)
layout.addSketch(lineSketch, {
position: new SKYMATH.Vector2D(0, -offset),
})

const valueLineSketch = new SKYCAD.Sketch()
valueLineSketch.moveTo(0, 0)
valueLineSketch.lineTo(0, -offset - 0.2 * textSize)

const arrowHeadSketch = new SKYCAD.Sketch()
arrowHeadSketch.moveTo(-0.2 * textSize, 0.05 * textSize)
arrowHeadSketch.lineTo(0, 0)
arrowHeadSketch.lineTo(-0.2 * textSize, -0.05 * textSize)

values.forEach((value) => {
layout.addSketch(valueLineSketch, {
position: new SKYMATH.Vector2D(value, 0),
})
layout.addSketch(arrowHeadSketch, {
position: new SKYMATH.Vector2D(value, -offset),
rotation: value > 0 ? 0 : Math.PI,
})
layout.addText(`${value.toFixed(decimals)}`, {
align: 'center',
position: new SKYMATH.Vector2D(value, -offset - 0.7 * textSize),
})
})
}
  • Example of use:
const layout = new SKYCAD.Layout()
const values = [-30, 70, 10, 30, 100, 150]
addLinearDimension(layout, values, {
textSize: 20,
decimals: 0,
offset: 35,
})