Angular Dimension
Angular dimensions measure and display angles between two directions in your 3D models. They're essential for technical drawings, engineering documentation, and design verification where angular relationships matter. Bitbybit's angular dimension tools help you create professional angular annotations that automatically update when your geometry changes.
Understanding Angular Dimensions
Angular dimensions measure the angle between two direction vectors and display them with arc lines, extension lines, and text labels. The system automatically calculates angles and formats the display. Key components include:
- Direction Vectors: Two direction vectors that define the angle being measured
- Center Point: The origin point from which the angle is measured
- Arc Radius: Controls the size of the dimensional arc
- Arc Offset: Positions the dimension arc relative to the center point
- Label Customization: For text formatting, units (degrees/radians), and positioning
- Rete
- Blockly
- TypeScript
{
"id": "rete-v2-json",
"nodes": {
"a1b2c3d4e5f6g7h8": {
"id": "a1b2c3d4e5f6g7h8",
"name": "bitbybit.vector.vectorXYZ",
"customName": "direction 1",
"async": false,
"drawable": true,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"x": 1,
"y": 0,
"z": 0
},
"inputs": {},
"position": [
7.482591014780979,
58.460446270459585
]
},
"b2c3d4e5f6g7h8i9": {
"id": "b2c3d4e5f6g7h8i9",
"name": "bitbybit.vector.vectorXYZ",
"customName": "direction 2",
"async": false,
"drawable": true,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"x": 0,
"y": 1,
"z": 1
},
"inputs": {},
"position": [
10.061801916378727,
411.1480178836501
]
},
"c3d4e5f6g7h8i9j0": {
"id": "c3d4e5f6g7h8i9j0",
"name": "bitbybit.occt.dimensions.simpleAngularDimension",
"customName": "angular dimension",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"radius": 2,
"offsetFromCenter": 0.3,
"extraSize": 0.1,
"decimalPlaces": 1,
"labelSuffix": "deg",
"labelSize": 0.3,
"labelOffset": 0.4,
"radians": false
},
"inputs": {
"direction1": {
"connections": [
{
"node": "a1b2c3d4e5f6g7h8",
"output": "result",
"data": {}
}
]
},
"direction2": {
"connections": [
{
"node": "b2c3d4e5f6g7h8i9",
"output": "result",
"data": {}
}
]
},
"center": {
"connections": [
{
"node": "d4e5f6g7h8i9j0k1",
"output": "result",
"data": {}
}
]
}
},
"position": [
570.2450515032658,
366.4814859166162
]
},
"d4e5f6g7h8i9j0k1": {
"id": "d4e5f6g7h8i9j0k1",
"name": "bitbybit.point.pointXYZ",
"customName": "center",
"async": false,
"drawable": true,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"x": 0,
"y": 0,
"z": 0
},
"inputs": {},
"position": [
7.392071876593093,
765.5571470674718
]
}
}
}
<xml xmlns="https://developers.google.com/blockly/xml"><variables><variable id="*cM!)eZ`SWWP:O-jO1rl">direction1</variable><variable id="US%1a6-s%$IBw4-r;O{0">direction2</variable><variable id="@3f[l%x)^,^k=QkE]hc|">center</variable></variables><block type="variables_set" id="|Um)Ma@j-zCu1;*pErp@" x="-183" y="-512"><field name="VAR" id="*cM!)eZ`SWWP:O-jO1rl">direction1</field><value name="VALUE"><block type="bitbybit.vector.vectorXYZ" id="dir1_vector"><value name="X"><block type="math_number" id="dir1_x"><field name="NUM">1</field></block></value><value name="Y"><block type="math_number" id="dir1_y"><field name="NUM">0</field></block></value><value name="Z"><block type="math_number" id="dir1_z"><field name="NUM">0</field></block></value></block></value><next><block type="variables_set" id="#|sI0xp23tki-Pabi`D("><field name="VAR" id="US%1a6-s%$IBw4-r;O{0">direction2</field><value name="VALUE"><block type="bitbybit.vector.vectorXYZ" id="dir2_vector"><value name="X"><block type="math_number" id="dir2_x"><field name="NUM">0</field></block></value><value name="Y"><block type="math_number" id="dir2_y"><field name="NUM">1</field></block></value><value name="Z"><block type="math_number" id="dir2_z"><field name="NUM">1</field></block></value></block></value><next><block type="variables_set" id=";{MlL9k.c=Y/n:1%wLF:"><field name="VAR" id="@3f[l%x)^,^k=QkE]hc|">center</field><value name="VALUE"><block type="bitbybit.point.pointXYZ" id="center_point"><value name="X"><block type="math_number" id="center_x"><field name="NUM">0</field></block></value><value name="Y"><block type="math_number" id="center_y"><field name="NUM">0</field></block></value><value name="Z"><block type="math_number" id="center_z"><field name="NUM">0</field></block></value></block></value><next><block type="bitbybit.draw.drawAnyAsyncNoReturn" id="draw_dimension"><value name="Entity"><block type="bitbybit.occt.dimensions.simpleAngularDimension" id="simple_angular_dimension"><value name="Direction1"><block type="variables_get" id="get_dir1"><field name="VAR" id="*cM!)eZ`SWWP:O-jO1rl">direction1</field></block></value><value name="Direction2"><block type="variables_get" id="get_dir2"><field name="VAR" id="US%1a6-s%$IBw4-r;O{0">direction2</field></block></value><value name="Center"><block type="variables_get" id="get_center"><field name="VAR" id="@3f[l%x)^,^k=QkE]hc|">center</field></block></value><value name="Radius"><block type="math_number" id="radius"><field name="NUM">2</field></block></value><value name="OffsetFromCenter"><block type="math_number" id="offset"><field name="NUM">0.3</field></block></value><value name="ExtraSize"><block type="math_number" id="extra_size"><field name="NUM">0.1</field></block></value><value name="DecimalPlaces"><block type="math_number" id="decimals"><field name="NUM">1</field></block></value><value name="LabelSuffix"><block type="text" id="suffix"><field name="TEXT">deg</field></block></value><value name="LabelSize"><block type="math_number" id="label_size"><field name="NUM">0.3</field></block></value><value name="LabelOffset"><block type="math_number" id="label_offset"><field name="NUM">0.4</field></block></value><value name="Radians"><block type="logic_boolean" id="radians"><field name="BOOL">FALSE</field></block></value></block></value></block></next></block></next></block></next></block></xml>
// Import the required DTO for angular dimensions
const { SimpleAngularDimensionDto } = Bit.Inputs.OCCT;
type Point3 = Bit.Inputs.Base.Point3;
type Vector3 = Bit.Inputs.Base.Vector3;
// Define the main function
const start = async () => {
// Define two direction vectors to measure angle between
const direction1: Vector3 = [1, 0, 0]; // X-axis direction
const direction2: Vector3 = [0, 1, 1]; // Direction at 45deg from Y and Z
const center: Point3 = [0, 0, 0]; // Origin point
// Create an angular dimension between the directions
const dimensionOptions = new SimpleAngularDimensionDto();
dimensionOptions.direction1 = direction1;
dimensionOptions.direction2 = direction2;
dimensionOptions.center = center;
dimensionOptions.radius = 2;
dimensionOptions.offsetFromCenter = 0.3;
dimensionOptions.extraSize = 0.1;
dimensionOptions.decimalPlaces = 1;
dimensionOptions.labelSuffix = "deg";
dimensionOptions.labelSize = 0.3;
dimensionOptions.labelOffset = 0.4;
dimensionOptions.radians = false;
// Create and draw the dimension
const dimension = await bitbybit.occt.dimensions.simpleAngularDimension(dimensionOptions);
bitbybit.draw.drawAnyAsync({ entity: dimension });
}
// Execute the function
start();
Angular dimensions update automatically when direction vectors change, keeping your documentation accurate throughout the design process.
Advanced Application: Cone Apex Angle
Angular dimensions are particularly useful for complex 3D geometry like cones, where measuring the apex angle is crucial for manufacturing and design verification. Here's an advanced example that creates a cone and measures its apex angle using angular dimensions.
- Rete
- Blockly
- TypeScript
{
"id": "rete-v2-json",
"nodes": {
"6000a6dba12c589b": {
"id": "6000a6dba12c589b",
"name": "bitbybit.occt.shapes.solid.createCone",
"customName": "cone",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"radius1": 5,
"radius2": 2.7,
"height": 5,
"angle": 360,
"center": [
0,
0,
0
],
"direction": [
0,
1,
0
]
},
"inputs": {
"radius2": {
"connections": [
{
"node": "0d1e3947d578b4ec",
"output": "result",
"data": {}
}
]
}
},
"position": [
202.90127182006836,
309.3927459716797
]
},
"3e6a6cd6b79a6182": {
"id": "3e6a6cd6b79a6182",
"name": "bitbybit.occt.transforms.rotate",
"customName": "rotate",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"axis": [
0,
0,
1
],
"angle": -90
},
"inputs": {
"shape": {
"connections": [
{
"node": "6000a6dba12c589b",
"output": "result",
"data": {}
}
]
},
"axis": {
"connections": [
{
"node": "5d1a4a4710b9c534",
"output": "result",
"data": {}
}
]
}
},
"position": [
848.8138999938965,
506.81813049316406
]
},
"5d1a4a4710b9c534": {
"id": "5d1a4a4710b9c534",
"name": "bitbybit.vector.vectorXYZ",
"customName": "vector xyz",
"async": false,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"x": 0,
"y": 1,
"z": 0
},
"inputs": {},
"position": [
202.6703758239746,
769.89697265625
]
},
"8de671c3eaab09de": {
"id": "8de671c3eaab09de",
"name": "bitbybit.occt.shapes.edge.getEdge",
"customName": "get edge",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"index": 2
},
"inputs": {
"shape": {
"connections": [
{
"node": "3e6a6cd6b79a6182",
"output": "result",
"data": {}
}
]
}
},
"position": [
1266.594482421875,
526.6192932128906
]
},
"02c13505f27ef023": {
"id": "02c13505f27ef023",
"name": "bitbybit.occt.shapes.edge.startPointOnEdge",
"customName": "start point on edge",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
}
},
"inputs": {
"shape": {
"connections": [
{
"node": "e96ef03bcb659862",
"output": "result",
"data": {}
}
]
}
},
"position": [
2118.7555152834793,
709.4557218388306
]
},
"664b0a741d144723": {
"id": "664b0a741d144723",
"name": "bitbybit.occt.shapes.edge.endPointOnEdge",
"customName": "end point on edge",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
}
},
"inputs": {
"shape": {
"connections": [
{
"node": "e96ef03bcb659862",
"output": "result",
"data": {}
}
]
}
},
"position": [
2126.2934115796666,
426.32490319306703
]
},
"0d5e7285ef133b23": {
"id": "0d5e7285ef133b23",
"name": "bitbybit.vector.sub",
"customName": "sub",
"async": false,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
}
},
"inputs": {
"first": {
"connections": [
{
"node": "664b0a741d144723",
"output": "result",
"data": {}
}
]
},
"second": {
"connections": [
{
"node": "02c13505f27ef023",
"output": "result",
"data": {}
}
]
}
},
"position": [
2598.625898772063,
482.4246994017498
]
},
"d23e3fb576119851": {
"id": "d23e3fb576119851",
"name": "bitbybit.occt.dimensions.simpleAngularDimension",
"customName": "simple angular dimension",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"direction1": [
1,
0,
0
],
"direction2": [
0,
0,
1
],
"center": [
0,
0,
0
],
"radius": 7,
"offsetFromCenter": 2,
"extraSize": 0,
"decimalPlaces": 2,
"labelSuffix": "(deg)",
"labelSize": 0.4,
"labelOffset": 0.6,
"radians": false
},
"inputs": {
"center": {
"connections": [
{
"node": "02c13505f27ef023",
"output": "result",
"data": {}
}
]
},
"direction1": {
"connections": [
{
"node": "0d5e7285ef133b23",
"output": "result",
"data": {}
}
]
},
"direction2": {
"connections": [
{
"node": "730d89b2fe4fb666",
"output": "result",
"data": {}
}
]
}
},
"position": [
3071.0977587390807,
628.4791643359932
]
},
"730d89b2fe4fb666": {
"id": "730d89b2fe4fb666",
"name": "bitbybit.vector.vectorXYZ",
"customName": "vector xyz",
"async": false,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"x": -1,
"y": 0,
"z": 0
},
"inputs": {},
"position": [
2612.4858041717157,
868.4008088631837
]
},
"e96ef03bcb659862": {
"id": "e96ef03bcb659862",
"name": "bitbybit.occt.transforms.translate",
"customName": "translate",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"translation": [
0,
0,
0
]
},
"inputs": {
"shape": {
"connections": [
{
"node": "8de671c3eaab09de",
"output": "result",
"data": {}
}
]
},
"translation": {
"connections": [
{
"node": "62a462cd9e796c3e",
"output": "result",
"data": {}
}
]
}
},
"position": [
1670.0430847458426,
523.7570313182497
]
},
"62a462cd9e796c3e": {
"id": "62a462cd9e796c3e",
"name": "bitbybit.vector.vectorXYZ",
"customName": "vector xyz",
"async": false,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"x": -1,
"y": 0,
"z": 0
},
"inputs": {},
"position": [
1269.73587503378,
839.2057481256558
]
},
"0d1e3947d578b4ec": {
"id": "0d1e3947d578b4ec",
"name": "bitbybit.math.numberSlider",
"customName": "number slider",
"data": {
"options": {
"min": 1,
"max": 10,
"step": 0.1,
"width": 350,
"updateOnDrag": false
},
"number": 1.1
},
"inputs": {},
"position": [
-343.14900917979224,
396.4478118682945
]
}
}
}
<xml xmlns="https://developers.google.com/blockly/xml"><variables><variable id="*cM!)eZ`SWWP:O-jO1rl">cone</variable><variable id="US%1a6-s%$IBw4-r;O{0">rotatedCone</variable><variable id="@3f[l%x)^,^k=QkE]hc|">coneEdge</variable><variable id="p7q8r9s0t1u2v3w4x5y6">translatedEdge</variable><variable id="z6y5x4w3v2u1t0s9r8q7">startPoint</variable><variable id="a1b2c3d4e5f6g7h8i9j0">endPoint</variable><variable id="k1l2m3n4o5p6q7r8s9t0">direction1</variable></variables><block type="variables_set" id="|Um)Ma@j-zCu1;*pErp@" x="-183" y="-512"><field name="VAR" id="*cM!)eZ`SWWP:O-jO1rl">cone</field><value name="VALUE"><block type="bitbybit.occt.shapes.solid.createCone" id="create_cone"><value name="Radius1"><block type="math_number" id="cone_radius1"><field name="NUM">5</field></block></value><value name="Radius2"><block type="math_number" id="cone_radius2"><field name="NUM">2.7</field></block></value><value name="Height"><block type="math_number" id="cone_height"><field name="NUM">5</field></block></value><value name="Angle"><block type="math_number" id="cone_angle"><field name="NUM">360</field></block></value><value name="Center"><block type="bitbybit.point.pointXYZ" id="cone_center"><value name="X"><block type="math_number" id="center_x"><field name="NUM">0</field></block></value><value name="Y"><block type="math_number" id="center_y"><field name="NUM">0</field></block></value><value name="Z"><block type="math_number" id="center_z"><field name="NUM">0</field></block></value></block></value><value name="Direction"><block type="bitbybit.vector.vectorXYZ" id="cone_direction"><value name="X"><block type="math_number" id="dir_x"><field name="NUM">0</field></block></value><value name="Y"><block type="math_number" id="dir_y"><field name="NUM">1</field></block></value><value name="Z"><block type="math_number" id="dir_z"><field name="NUM">0</field></block></value></block></value></block></value><next><block type="variables_set" id="#|sI0xp23tki-Pabi`D("><field name="VAR" id="US%1a6-s%$IBw4-r;O{0">rotatedCone</field><value name="VALUE"><block type="bitbybit.occt.transforms.rotate" id="rotate_cone"><value name="Shape"><block type="variables_get" id="get_cone"><field name="VAR" id="*cM!)eZ`SWWP:O-jO1rl">cone</field></block></value><value name="Axis"><block type="bitbybit.vector.vectorXYZ" id="rotation_axis"><value name="X"><block type="math_number" id="rot_axis_x"><field name="NUM">0</field></block></value><value name="Y"><block type="math_number" id="rot_axis_y"><field name="NUM">1</field></block></value><value name="Z"><block type="math_number" id="rot_axis_z"><field name="NUM">0</field></block></value></block></value><value name="Angle"><block type="math_number" id="rotation_angle"><field name="NUM">-90</field></block></value></block></value><next><block type="variables_set" id=";{MlL9k.c=Y/n:1%wLF:"><field name="VAR" id="@3f[l%x)^,^k=QkE]hc|">coneEdge</field><value name="VALUE"><block type="bitbybit.occt.shapes.edge.getEdge" id="get_edge"><value name="Shape"><block type="variables_get" id="get_rotated_cone"><field name="VAR" id="US%1a6-s%$IBw4-r;O{0">rotatedCone</field></block></value><value name="Index"><block type="math_number" id="edge_index"><field name="NUM">2</field></block></value></block></value><next><block type="variables_set" id="translate_edge_var"><field name="VAR" id="p7q8r9s0t1u2v3w4x5y6">translatedEdge</field><value name="VALUE"><block type="bitbybit.occt.transforms.translate" id="translate_edge"><value name="Shape"><block type="variables_get" id="get_edge_for_translate"><field name="VAR" id="@3f[l%x)^,^k=QkE]hc|">coneEdge</field></block></value><value name="Translation"><block type="bitbybit.vector.vectorXYZ" id="translation_vector"><value name="X"><block type="math_number" id="trans_x"><field name="NUM">-1</field></block></value><value name="Y"><block type="math_number" id="trans_y"><field name="NUM">0</field></block></value><value name="Z"><block type="math_number" id="trans_z"><field name="NUM">0</field></block></value></block></value></block></value><next><block type="variables_set" id="get_start_point_var"><field name="VAR" id="z6y5x4w3v2u1t0s9r8q7">startPoint</field><value name="VALUE"><block type="base_time_await_return" id="FCD}Yr.~w#,E{y/[3*mT"><value name="Promise"><block type="bitbybit.occt.shapes.edge.startPointOnEdge" id="get_start_point"><value name="Shape"><block type="variables_get" id="get_translated_edge_start"><field name="VAR" id="p7q8r9s0t1u2v3w4x5y6">translatedEdge</field></block></value></block></value></block></value><next><block type="variables_set" id="get_end_point_var"><field name="VAR" id="a1b2c3d4e5f6g7h8i9j0">endPoint</field><value name="VALUE"><block type="base_time_await_return" id="#yHstX*jre:,ySK0%V?c"><value name="Promise"><block type="bitbybit.occt.shapes.edge.endPointOnEdge" id="get_end_point"><value name="Shape"><block type="variables_get" id="get_translated_edge_end"><field name="VAR" id="p7q8r9s0t1u2v3w4x5y6">translatedEdge</field></block></value></block></value></block></value><next><block type="variables_set" id="calc_direction_var"><field name="VAR" id="k1l2m3n4o5p6q7r8s9t0">direction1</field><value name="VALUE"><block type="bitbybit.vector.sub" id="calc_direction"><value name="First"><block type="variables_get" id="get_end_for_sub"><field name="VAR" id="a1b2c3d4e5f6g7h8i9j0">endPoint</field></block></value><value name="Second"><block type="variables_get" id="get_start_for_sub"><field name="VAR" id="z6y5x4w3v2u1t0s9r8q7">startPoint</field></block></value></block></value><next><block type="bitbybit.draw.drawAnyAsyncNoReturn" id="draw_cone"><value name="Entity"><block type="variables_get" id="draw_rotated_cone"><field name="VAR" id="US%1a6-s%$IBw4-r;O{0">rotatedCone</field></block></value><next><block type="bitbybit.draw.drawAnyAsyncNoReturn" id="draw_dimension"><value name="Entity"><block type="bitbybit.occt.dimensions.simpleAngularDimension" id="angular_dimension"><value name="Direction1"><block type="variables_get" id="get_direction1"><field name="VAR" id="k1l2m3n4o5p6q7r8s9t0">direction1</field></block></value><value name="Direction2"><block type="bitbybit.vector.vectorXYZ" id="direction2_vector"><value name="X"><block type="math_number" id="dir2_x"><field name="NUM">-1</field></block></value><value name="Y"><block type="math_number" id="dir2_y"><field name="NUM">0</field></block></value><value name="Z"><block type="math_number" id="dir2_z"><field name="NUM">0</field></block></value></block></value><value name="Center"><block type="variables_get" id="get_start_center"><field name="VAR" id="z6y5x4w3v2u1t0s9r8q7">startPoint</field></block></value><value name="Radius"><block type="math_number" id="dimension_radius"><field name="NUM">7</field></block></value><value name="OffsetFromCenter"><block type="math_number" id="offset_from_center"><field name="NUM">2</field></block></value><value name="ExtraSize"><block type="math_number" id="extra_size"><field name="NUM">0</field></block></value><value name="DecimalPlaces"><block type="math_number" id="decimal_places"><field name="NUM">2</field></block></value><value name="LabelSuffix"><block type="text" id="label_suffix"><field name="TEXT">(deg)</field></block></value><value name="LabelSize"><block type="math_number" id="label_size"><field name="NUM">0.4</field></block></value><value name="LabelOffset"><block type="math_number" id="label_offset"><field name="NUM">0.6</field></block></value><value name="Radians"><block type="logic_boolean" id="use_radians"><field name="BOOL">FALSE</field></block></value></block></value></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></xml>
// Import required DTOs for creating shapes and dimensions
const { ConeDto, SimpleAngularDimensionDto } = Bit.Inputs.OCCT;
// Import types for type safety
type TopoDSSolidPointer = Bit.Inputs.OCCT.TopoDSSolidPointer;
type TopoDSEdgePointer = Bit.Inputs.OCCT.TopoDSEdgePointer;
type Point3 = Bit.Inputs.Base.Point3;
type Vector3 = Bit.Inputs.Base.Vector3;
// Get access to OCCT modules
const { shapes, dimensions, transforms } = bitbybit.occt;
const { solid, edge } = shapes;
// Define the main function to create a cone with angular dimension
const start = async () => {
// Create a cone with specific dimensions
const coneOptions = new ConeDto();
coneOptions.radius1 = 5;
coneOptions.radius2 = 2.7; // Variable radius for apex angle
coneOptions.height = 5;
coneOptions.angle = 360;
coneOptions.center = [0, 0, 0];
coneOptions.direction = [0, 1, 0];
const cone = await solid.createCone(coneOptions);
// Rotate the cone -90 degrees around Y axis for better visualization
const rotatedCone = await transforms.rotate({
shape: cone,
axis: [0, 1, 0],
angle: -90
});
// Draw the rotated cone
bitbybit.draw.drawAnyAsync({ entity: rotatedCone });
// Get edge 2 from the cone (this is a generatrix line)
const coneEdge = await edge.getEdge({ shape: rotatedCone, index: 2 });
// Translate the edge to position it for measurement
const translatedEdge = await transforms.translate({
shape: coneEdge,
translation: [-1, 0, 0]
});
// Get start and end points from the translated edge
const startPoint = await edge.startPointOnEdge({ shape: translatedEdge });
const endPoint = await edge.endPointOnEdge({ shape: translatedEdge });
// Calculate direction vector from start to end point
const direction1 = bitbybit.vector.sub({ first: endPoint, second: startPoint }) as Vector3;
// Create angular dimension to measure apex angle
const dimensionOptions = new SimpleAngularDimensionDto();
dimensionOptions.direction1 = direction1;
dimensionOptions.direction2 = [-1, 0, 0]; // Reference direction
dimensionOptions.center = startPoint; // Apex point
dimensionOptions.radius = 7;
dimensionOptions.offsetFromCenter = 2;
dimensionOptions.extraSize = 0;
dimensionOptions.decimalPlaces = 2;
dimensionOptions.labelSuffix = "(deg)";
dimensionOptions.labelSize = 0.4;
dimensionOptions.labelOffset = 0.6;
dimensionOptions.radians = false;
// Create and draw the angular dimension
const dimension = await dimensions.simpleAngularDimension(dimensionOptions);
bitbybit.draw.drawAnyAsync({ entity: dimension });
}
// Execute the function
start();
This example demonstrates how angular dimensions can be applied to complex 3D geometry. The cone's apex angle is measured between two direction vectors from the apex to opposite points on the base circumference. As you adjust the cone's radius or height, the apex angle automatically updates, making this perfect for manufacturing documentation and design verification.
Dimension Properties and Customization
Angular dimensions offer extensive customization options to match your documentation standards and specific use cases.
Essential Parameters
Direction Vectors define the two directions between which the angle is measured. These can be:
- Fixed direction vectors like
[1, 0, 0]and[0, 1, 0] - Calculated vectors from geometry using
vectorXYZ - Dynamic vectors that change based on parameters
Center Point is the origin from which the angle is measured. This should typically be:
- The vertex where the two directions meet
- A significant geometric point in your design
- Positioned for optimal dimension visibility
Radius controls the size of the dimensional arc. Larger radii provide:
- Better visibility in complex drawings
- More space for dimension text
- Clearer separation from geometry
Offset from Center moves the dimension arc away from the center point:
- Positive values move the arc outward
- Negative values move it inward
- Use this to avoid overlapping with geometry
Label Formatting
Decimal Places controls measurement precision:
- Use 0-1 decimals for rough angles
- Use 2-3 decimals for precision machining
- Consider the manufacturing tolerance requirements
Label Suffix adds context to measurements:
"deg"for simple degree notation"deg apex"for specific angle types"(deg)"for formal documentation"rad"when using radians
Radians vs Degrees can be controlled with the radians property:
false(default) displays angles in degrees (0-360 deg)truedisplays angles in radians (0-2π)
Label Size and Offset control text appearance:
- Scale label size for viewing distance and drawing scale
- Use label offset to position text optimally
- Consider text readability at different zoom levels
Extra Size controls the length of extension lines:
- Helps connect the dimension to referenced geometry
- Useful when the center point is far from the measured elements
- Improves dimension clarity in complex drawings
Best Practices
Angular dimensions serve critical functions in engineering and manufacturing workflows, communicating design intent for machined angles, verifying angular tolerances, and ensuring proper fit between angled components. Position dimensions near the vertex where angles originate, use appropriate radius values to avoid crowding, and maintain consistent formatting throughout your documentation.
These dimensions excel in machining operations for documenting drill and chamfer angles, structural design for measuring beam and joint angles, and quality control for checking manufactured parts against specifications. When integrated with parametric design workflows, they become especially powerful by automatically updating as design parameters change, validating constraints, and creating interactive documentation.
Angular dimensions bridge the critical gap between design intent and manufacturing reality. They provide a common language for communicating angular relationships in collaborative environments, eliminate manual calculations, and reduce downstream errors. Whether you're working with simple geometric relationships or complex 3D assemblies like the cone apex angle example, mastering angular dimensions improves documentation quality and clarity, leading to reduced errors, faster manufacturing, and clearer communication across your entire design and production workflow.



