or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

booleans.mdcolors.mdcurves.mdexpansions-modifiers.mdextrusions.mdgeometries.mdhulls.mdindex.mdmaths.mdmeasurements.mdprimitives.mdtext-utils.mdtransforms.md
tile.json

text-utils.mddocs/

0

# Text and Utilities

1

2

This module provides text rendering capabilities for creating 2D/3D text outlines and various utility functions for angle conversions, data processing, and geometry validation.

3

4

## Text Capabilities

5

6

Texts provide sets of segments for each character or text strings. The segments can be used to create outlines for both 2D and 3D geometry. Note: Only ASCII characters are supported.

7

8

### Vector Text

9

10

Generate vector text as line segments for creating text outlines.

11

12

```javascript { .api }

13

/**

14

* Generate vector text as line segments from text string

15

* @param {Object} options - Text options

16

* @param {Number} [options.xOffset=0] - X offset for text positioning

17

* @param {Number} [options.yOffset=0] - Y offset for text positioning

18

* @param {Number} [options.height=21] - Height of text characters

19

* @param {Number} [options.extrudeOffset=0] - Offset for 3D extrusion preparation

20

* @param {String} [options.input] - Text string to convert (deprecated, use text parameter)

21

* @param {String} text - Text string to convert to vector segments

22

* @returns {Array} Array of line segment arrays, each representing character outlines

23

*/

24

function vectorText(options: {

25

xOffset?: number,

26

yOffset?: number,

27

height?: number,

28

extrudeOffset?: number,

29

input?: string

30

}, text: string): Array<Array<[number, number]>>;

31

```

32

33

**Usage Examples:**

34

35

```javascript

36

const { vectorText } = require('@jscad/modeling').text;

37

const { extrudeLinear } = require('@jscad/modeling').extrusions;

38

const { geom2 } = require('@jscad/modeling').geometries;

39

40

// Create simple text outline

41

const textSegments = vectorText({}, 'HELLO');

42

// Returns array of line segment arrays for each character

43

44

// Create text with custom positioning and size

45

const largeText = vectorText({

46

xOffset: 10,

47

yOffset: 5,

48

height: 42

49

}, 'BIG TEXT');

50

51

// Convert text segments to 2D geometries for further processing

52

const textGeometries = textSegments.map(segments => {

53

// Each segments array represents one character

54

return geom2.fromPoints(segments);

55

});

56

57

// Create 3D text by extruding

58

const text3D = textGeometries.map(geom =>

59

extrudeLinear({ height: 5 }, geom)

60

);

61

```

62

63

### Vector Character

64

65

Generate vector segments for individual characters.

66

67

```javascript { .api }

68

/**

69

* Generate vector segments for a single character

70

* @param {Object} options - Character options

71

* @param {Number} [options.xOffset=0] - X offset for character positioning

72

* @param {Number} [options.yOffset=0] - Y offset for character positioning

73

* @param {Number} [options.height=21] - Height of character

74

* @param {String} character - Single character to convert (ASCII only)

75

* @returns {Array} Array of line segments representing the character outline

76

*/

77

function vectorChar(options: {

78

xOffset?: number,

79

yOffset?: number,

80

height?: number

81

}, character: string): Array<[number, number]>;

82

```

83

84

**Usage Examples:**

85

86

```javascript

87

const { vectorChar } = require('@jscad/modeling').text;

88

89

// Get segments for individual character

90

const letterA = vectorChar({}, 'A');

91

const letterB = vectorChar({ xOffset: 30 }, 'B'); // Offset to position next to A

92

93

// Create custom character with scaling

94

const bigLetter = vectorChar({ height: 100 }, 'X');

95

96

// Build custom text by combining characters

97

const customText = [];

98

const characters = 'CUSTOM';

99

let currentOffset = 0;

100

101

characters.split('').forEach(char => {

102

const charSegments = vectorChar({

103

xOffset: currentOffset,

104

height: 30

105

}, char);

106

customText.push(charSegments);

107

currentOffset += 25; // Space between characters

108

});

109

```

110

111

## Utility Functions

112

113

Utility functions of various sorts, including conversions from different angular measures and data processing helpers.

114

115

### Angle Conversions

116

117

Convert between degrees and radians.

118

119

```javascript { .api }

120

/**

121

* Convert degrees to radians

122

* @param {Number} degrees - Angle in degrees

123

* @returns {Number} Angle in radians

124

*/

125

function degToRad(degrees: number): number;

126

127

/**

128

* Convert radians to degrees

129

* @param {Number} radians - Angle in radians

130

* @returns {Number} Angle in degrees

131

*/

132

function radToDeg(radians: number): number;

133

```

134

135

**Usage Examples:**

136

137

```javascript

138

const { degToRad, radToDeg } = require('@jscad/modeling').utils;

139

140

// Convert common angles

141

const rightAngleRad = degToRad(90); // π/2 ≈ 1.5708

142

const halfTurnRad = degToRad(180); // π ≈ 3.1416

143

const fullTurnRad = degToRad(360); // 2π ≈ 6.2832

144

145

// Convert back to degrees

146

const degrees90 = radToDeg(Math.PI / 2); // 90

147

const degrees180 = radToDeg(Math.PI); // 180

148

const degrees360 = radToDeg(Math.PI * 2); // 360

149

150

// Use in geometric calculations

151

const { rotateZ } = require('@jscad/modeling').transforms;

152

const { cube } = require('@jscad/modeling').primitives;

153

154

const myCube = cube({ size: 10 });

155

const rotated45 = rotateZ(degToRad(45), myCube);

156

const rotated90 = rotateZ(degToRad(90), myCube);

157

```

158

159

### Data Processing

160

161

Utilities for processing arrays and geometric data.

162

163

```javascript { .api }

164

/**

165

* Flatten nested arrays into a single-level array

166

* @param {Array} array - Nested array to flatten

167

* @returns {Array} Flattened array

168

*/

169

function flatten(array: any[]): any[];

170

171

/**

172

* Insert item into sorted array at correct position

173

* @param {*} item - Item to insert

174

* @param {Array} array - Sorted array to insert into

175

* @param {Function} [compareFn] - Comparison function for sorting

176

* @returns {Array} Array with item inserted

177

*/

178

function insertSorted(item: any, array: any[], compareFn?: (a: any, b: any) => number): any[];

179

180

/**

181

* Numeric sort comparison function

182

* @param {Number} a - First number

183

* @param {Number} b - Second number

184

* @returns {Number} Comparison result (-1, 0, or 1)

185

*/

186

function fnNumberSort(a: number, b: number): number;

187

```

188

189

**Usage Examples:**

190

191

```javascript

192

const { flatten, insertSorted, fnNumberSort } = require('@jscad/modeling').utils;

193

194

// Flatten nested arrays

195

const nested = [[1, 2], [3, [4, 5]], 6];

196

const flat = flatten(nested); // [1, 2, 3, 4, 5, 6]

197

198

// Use with geometry operations

199

const { union } = require('@jscad/modeling').booleans;

200

const nestedShapes = [

201

[cube({ size: 1 }), cube({ size: 2 })],

202

[sphere({ radius: 1 }), sphere({ radius: 2 })]

203

];

204

const allShapes = flatten(nestedShapes);

205

const combined = union(...allShapes);

206

207

// Insert into sorted array

208

const sortedNumbers = [1, 3, 5, 7, 9];

209

const withInserted = insertSorted(6, sortedNumbers, fnNumberSort);

210

// Result: [1, 3, 5, 6, 7, 9]

211

212

// Sort numeric array

213

const unsorted = [3.7, 1.2, 8.9, 2.1, 5.6];

214

const sorted = unsorted.sort(fnNumberSort); // [1.2, 2.1, 3.7, 5.6, 8.9]

215

```

216

217

### Geometry Validation

218

219

Utilities for validating and analyzing geometric data.

220

221

```javascript { .api }

222

/**

223

* Check if all shapes in array are the same type

224

* @param {Array} shapes - Array of geometry objects to check

225

* @returns {Boolean} True if all shapes are the same type

226

*/

227

function areAllShapesTheSameType(shapes: any[]): boolean;

228

```

229

230

**Usage Examples:**

231

232

```javascript

233

const { areAllShapesTheSameType } = require('@jscad/modeling').utils;

234

const { cube, sphere } = require('@jscad/modeling').primitives;

235

const { circle, rectangle } = require('@jscad/modeling').primitives;

236

237

// Check 3D shapes

238

const shapes3D = [cube({ size: 5 }), cube({ size: 3 }), cube({ size: 8 })];

239

const allSameType3D = areAllShapesTheSameType(shapes3D); // true (all geom3)

240

241

// Check mixed shapes

242

const mixedShapes = [cube({ size: 5 }), circle({ radius: 3 })];

243

const allSameTypeMixed = areAllShapesTheSameType(mixedShapes); // false (geom3 and geom2)

244

245

// Use for validation before boolean operations

246

const { union } = require('@jscad/modeling').booleans;

247

const validateAndUnion = (shapes) => {

248

if (!areAllShapesTheSameType(shapes)) {

249

throw new Error('All shapes must be the same type for boolean operations');

250

}

251

return union(...shapes);

252

};

253

```

254

255

### Segment Calculation

256

257

Calculate appropriate segment counts for curved shapes.

258

259

```javascript { .api }

260

/**

261

* Calculate number of segments for given radius to maintain smoothness

262

* @param {Number} radius - Radius of curved shape

263

* @returns {Number} Recommended number of segments

264

*/

265

function radiusToSegments(radius: number): number;

266

```

267

268

**Usage Examples:**

269

270

```javascript

271

const { radiusToSegments } = require('@jscad/modeling').utils;

272

const { circle, cylinder } = require('@jscad/modeling').primitives;

273

274

// Calculate appropriate segments for different radii

275

const smallRadius = 2;

276

const mediumRadius = 10;

277

const largeRadius = 50;

278

279

const smallSegments = radiusToSegments(smallRadius); // ~16

280

const mediumSegments = radiusToSegments(mediumRadius); // ~32

281

const largeSegments = radiusToSegments(largeRadius); // ~64

282

283

// Use for creating smooth curves

284

const smoothCircles = [

285

circle({ radius: smallRadius, segments: smallSegments }),

286

circle({ radius: mediumRadius, segments: mediumSegments }),

287

circle({ radius: largeRadius, segments: largeSegments })

288

];

289

290

// Apply to 3D shapes

291

const smoothCylinder = cylinder({

292

radius: 15,

293

height: 10,

294

segments: radiusToSegments(15)

295

});

296

```

297

298

## Advanced Text and Utility Techniques

299

300

### Custom Text Layout

301

302

Create complex text layouts with multiple lines and formatting:

303

304

```javascript

305

const { vectorText, vectorChar } = require('@jscad/modeling').text;

306

const { degToRad } = require('@jscad/modeling').utils;

307

const { rotateZ, translate } = require('@jscad/modeling').transforms;

308

309

// Multi-line text layout

310

const createMultilineText = (lines, options = {}) => {

311

const {

312

lineHeight = 30,

313

characterSpacing = 25,

314

height = 21

315

} = options;

316

317

const textGeometries = [];

318

319

lines.forEach((line, lineIndex) => {

320

let xOffset = 0;

321

line.split('').forEach(char => {

322

if (char !== ' ') {

323

const charSegments = vectorChar({

324

xOffset,

325

yOffset: -lineIndex * lineHeight,

326

height

327

}, char);

328

textGeometries.push(charSegments);

329

}

330

xOffset += characterSpacing;

331

});

332

});

333

334

return textGeometries;

335

};

336

337

const multilineText = createMultilineText([

338

'LINE ONE',

339

'LINE TWO',

340

'LINE THREE'

341

]);

342

```

343

344

### Curved Text

345

346

Create text along curved paths:

347

348

```javascript

349

const { vectorChar } = require('@jscad/modeling').text;

350

const { degToRad, radToDeg } = require('@jscad/modeling').utils;

351

const { rotateZ, translate } = require('@jscad/modeling').transforms;

352

353

// Text along circular arc

354

const createArcText = (text, radius, startAngle = 0) => {

355

const chars = text.split('');

356

const angleStep = degToRad(15); // Angle between characters

357

358

return chars.map((char, index) => {

359

const angle = startAngle + (index * angleStep);

360

const x = Math.cos(angle) * radius;

361

const y = Math.sin(angle) * radius;

362

363

// Create character and position/rotate it

364

const charSegments = vectorChar({}, char);

365

return translate([x, y, 0],

366

rotateZ(angle + Math.PI/2, charSegments)

367

);

368

});

369

};

370

371

const arcText = createArcText('CURVED TEXT', 50, degToRad(0));

372

```

373

374

### Batch Processing Utilities

375

376

Process large datasets efficiently:

377

378

```javascript

379

const { flatten, areAllShapesTheSameType } = require('@jscad/modeling').utils;

380

const { union } = require('@jscad/modeling').booleans;

381

382

// Batch process shapes with validation

383

const batchProcess = (shapeGroups, operation) => {

384

const flatShapes = flatten(shapeGroups);

385

386

// Group by type

387

const groupedByType = {};

388

flatShapes.forEach(shape => {

389

const type = shape.type || 'unknown';

390

if (!groupedByType[type]) {

391

groupedByType[type] = [];

392

}

393

groupedByType[type].push(shape);

394

});

395

396

// Process each type group

397

const results = [];

398

Object.values(groupedByType).forEach(typeGroup => {

399

if (areAllShapesTheSameType(typeGroup)) {

400

results.push(operation(...typeGroup));

401

}

402

});

403

404

return results;

405

};

406

407

// Usage

408

const shapeGroups = [

409

[cube({ size: 1 }), cube({ size: 2 })],

410

[circle({ radius: 1 }), circle({ radius: 2 })]

411

];

412

const processed = batchProcess(shapeGroups, union);

413

```

414

415

### Performance Optimization

416

417

Optimize operations using utility functions:

418

419

```javascript

420

const { radiusToSegments, fnNumberSort } = require('@jscad/modeling').utils;

421

422

// Adaptive detail levels

423

const createAdaptiveDetail = (shapes) => {

424

return shapes.map(shape => {

425

if (shape.radius) {

426

const segments = radiusToSegments(shape.radius);

427

return { ...shape, segments };

428

}

429

return shape;

430

});

431

};

432

433

// Efficient sorting for geometric data

434

const sortGeometricData = (points) => {

435

// Sort by distance from origin

436

return points.sort((a, b) => {

437

const distA = Math.sqrt(a[0]*a[0] + a[1]*a[1]);

438

const distB = Math.sqrt(b[0]*b[0] + b[1]*b[1]);

439

return fnNumberSort(distA, distB);

440

});

441

};

442

```