## Other Primitives

### Path

A path is a series of points, connected by very thin (invisible) line segments. Paths can be created as a `line` from an array of points, or by calling various functions to create or extend another path.

```const { line } = require('@jscad/modeling').primitives
const { path2 } = require('@jscad/modeling').geometries

const mypathA = line([[10, 10], [-10, 10]])
const mypathB = line([[-10, -10], [10, -10]])
let mypath = path2.concat(mypathA, mypathB)
mypath = path2.close(mypath)```

In addition, a path can be open or closed. An open path is typically used to create another by appending additional points. A closed path is final, and has a line segment between first and last points.

The 'path2' geometry is accessed through the modeling API using the following:

`const { path2 } = require('@jscad/modeling').geometries`

#### Curved Paths

Curved paths can also be simulated. Paths can be created as an 'arc'. (See Appending Points below for more options.) The 'arc' primitive creates a curved path about a `center`. The arc is created from line segments placed the same distance from the `center`, at the given `radius`. Start and end angles for the arc can also be supplied. The `segments` specify the number of segments to create per full rotation.

Defaults:

• center : [0, 0]
• startAngle : 0
• endAngle : PI * 2
• segments : 32
```const { arc } = require('@jscad/modeling').primitives

const mypath = arc({radius: 5, startAngle: Math.PI / 2})
const mypath = arc({center: [5, 5], radius: 5, startAngle: Math.PI, endAngle: Math.PI / 2, segments: 4})```

#### Appending Points

Any number of points can be appended to a path, which produces a new path.

```const { path2 } = require('@jscad/modeling').geometries
const { line } = require('@jscad/modeling').primitives

const mypath = line([[27, -22], [27, 22]])
const newpath = path2.appendPoints([[-27, 22], [-27, -27], [27, -22]], mypath)```

An 'arc' can be appended to a path as well, which creates a series of line segments that simulate an 'arc'.

Defaults:

• clockwise : false
• large : false
• segments : 32

Note: This implementation follows the SVG specifications.

```const { path2 } = require('@jscad/modeling').geometries

let p1 = path2.create([[10,-20]])
p1 = path2.appendPoints([[27.5,-3.28125]], p1)
p1 = path2.appendArc({endpoint: [12.5, -22.96875], radius: [15, -19.6875]}, p1)```

In addition, 'bézier' curves can be appended to a path, which creates a series of line segments that simulate a 'bézier' curve.

The 'bézier' curve starts at the last point in the given path, and ends at the last control point. The other control points are intermediate control points to transition the curve from start to end points. The first control point may be 'null' to ensure a smooth transition occurs between curves.

Note: This implementation follows the SVG specifications.

```const { path2 } = require('@jscad/modeling').geometries

let p5 = path2.create([[10,-20]])
p5 = path2.appendBezier({controlPoints: [[10,-10],[25,-10],[25,-20]]}, p5)
p5 = path2.appendBezier({controlPoints: [null, [25,-30],[40,-30],[40,-20]]}, p5)```

#### Conversion to 2D Shape

There are many ways to convert paths into to two dimensional shapes. The following provide some examples.

First, a two dimensional shape can be created from the points inside a path, but the path must be closed.

```const { geom2, path2 } = require('@jscad/modeling').geometries
const { line } = require('@jscad/modeling').primitives

// create a closed path in shape of triangle
const mypath = line([[10, 10], [-10, 10], [-10, -10], [10, 10]])
const myshape = geom2.fromPoints(path2.toPoints(mypath))```

Second, a path can be expanded into a two dimensional shape. The result is a two dimensional shape that fits around the path.

```// create an open path in shape of L
const { expand } = require('@jscad/modeling').expansions
const { line } = require('@jscad/modeling').primitives

const mypath = line([[10, 10], [-10, 10], [-10, -10]])
const myshape = expand({delta: 2, corners: 'chamfer'}, mypath)```

#### Conversion to 3D Shape

Two dimensional shapes can be extruded into three dimensional shapes.

```const { path2 } = require('@jscad/modeling').geometries
const { extrudeLinear } = require('@jscad/modeling').extrusions

// create a closed path in shape of triangle
const mypath = path2.fromPoints({ closed: true }, [[0, 0], [12, 0], [6, 10]])
// extrude into triangular prism
const myshape = extrudeLinear({ height: 15 }, mypath)```

### Text

Text can be used in designs to create the outline of characters, which can then be used to create either 2D or 3D shapes.

NOTE: Only the ASCII characters can be used today.

#### Single Characters

A single character can be converted into an outline, i.e. an array of line segments. The character `height` as well as the character position can be requested by specifying options. Note: The `height` is the height of UPPERCASE characters.

Defaults:

• xOffset : 0
• yOffset : 0
• height : 21
• extrudeOffset : 0
• font : 'hershey simplex' (built in)
```const { vectorChar } = require('@jscad/modeling').text

const outlines = vectorChar('H');
const outlines = vectorChar({ height: 50 }, 'i');```

The above examples only create the outlines of the character. In order to convert to something useful, the following can be used to convert the outlines (segments) into paths.

```const { path2 } = require('@jscad/modeling').geometries

const segmentToPath = (segment) => {
return path2.fromPoints({close: false}, segment)
}

const paths = outlines.segments.map((segment) => segmentToPath(segment))```

And of course, the paths can be used to create additional shapes, including 3D shapes of the characters.

#### Text Strings

In addition to single characters, complete text strings can be converted to a series of outlines, i.e. line segments. Text can be split into multiple lines by including '\n'. And of course, text can be aligned and spaced by specifying options.

Defaults:

• xOffset : 0
• yOffset : 0
• height : 21
• lineSpacing = 1.4
• letterSpacing = 1
• align = 'left'
• extrudeOffset : 0
• font : 'hershey simplex' (built in)
```const { vectorText } = require('@jscad/modeling').text

const outlines = vectorText({ yOffset: -90, height: 10, extrudeOffset: 2, input: 'JSCAD is awesome!' });
const outlines = vectorText({ height: 25, align: 'right', lineSpacing: 2.2, extrudeOffset: 2 }, 'JSCAD\nRocks!!');```

Again, you will have to convert the output of `vectorText` into a list of paths before it becomes actually useful:

```const { path2 } = require('@jscad/modeling').geometries

const segmentToPath = (segment) => {
return path2.fromPoints({close: false}, segment)
}

const paths = outlines.map((segment) => segmentToPath(segment))```

#### Using Other Fonts

The default font (hershey simplex) was provided from the JSCAD Vector Font project. This project includes several 'compiled' fonts that can be used immediately, as well as a utility to convert singe-line fonts.

Once the custom 'compiled' font is availabe, here are the steps to use it.

1. Create a new project
2. Copy the custom 'compiled' font into the project
3. Require the custom font inside the project design
4. Specify the 'font' in the options to vectorChar() or vectorText()
```const { path2 } = require('@jscad/modeling').geometries
const { vectorText } = require('@jscad/modeling').text

const myfont = require('./fonts/vector/cncVector') // CUSTOM FONT

const segmentToPath = (segment) => {
return path2.fromPoints({close: false}, segment)
}

const main = () => {
const outlines = vectorText({height: 42, align: 'right', font: myfont}, 'JSCAD\nROCKS!!')
const paths = outlines.map((segment) => segmentToPath(segment))
return paths
}

module.exports = {main}```

Special Note: These fonts are 'single-line' fonts, NOT TrueType fonts. There are libraries that create outlines from TrueType (and other) fonts.