figureone 0.15.10 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (159) hide show
  1. package/figureone.min.js +1 -1
  2. package/index.js +79167 -0
  3. package/package.json +15 -1
  4. package/types/index.d.ts +132 -0
  5. package/types/js/figure/Animation/Animation.d.ts +36 -0
  6. package/types/js/figure/Animation/AnimationBuilder.d.ts +173 -0
  7. package/types/js/figure/Animation/AnimationManager.d.ts +392 -0
  8. package/types/js/figure/Animation/AnimationStep/CustomStep.d.ts +99 -0
  9. package/types/js/figure/Animation/AnimationStep/DelayStep.d.ts +24 -0
  10. package/types/js/figure/Animation/AnimationStep/ElementAnimationStep/ColorAnimationStep.d.ts +203 -0
  11. package/types/js/figure/Animation/AnimationStep/ElementAnimationStep/OpacityAnimationStep.d.ts +220 -0
  12. package/types/js/figure/Animation/AnimationStep/ElementAnimationStep/PositionAnimationStep.d.ts +124 -0
  13. package/types/js/figure/Animation/AnimationStep/ElementAnimationStep/PulseAnimationStep.d.ts +137 -0
  14. package/types/js/figure/Animation/AnimationStep/ElementAnimationStep/PulseTransformAnimationStep.d.ts +52 -0
  15. package/types/js/figure/Animation/AnimationStep/ElementAnimationStep/RotationAnimationStep.d.ts +119 -0
  16. package/types/js/figure/Animation/AnimationStep/ElementAnimationStep/ScaleAnimationStep.d.ts +93 -0
  17. package/types/js/figure/Animation/AnimationStep/ElementAnimationStep/ScenarioAnimationStep.d.ts +204 -0
  18. package/types/js/figure/Animation/AnimationStep/ElementAnimationStep/TransformAnimationStep.d.ts +163 -0
  19. package/types/js/figure/Animation/AnimationStep/ElementAnimationStep.d.ts +56 -0
  20. package/types/js/figure/Animation/AnimationStep/ParallelAnimationStep.d.ts +70 -0
  21. package/types/js/figure/Animation/AnimationStep/SerialAnimationStep.d.ts +84 -0
  22. package/types/js/figure/Animation/AnimationStep/TriggerStep.d.ts +106 -0
  23. package/types/js/figure/Animation/AnimationStep.d.ts +110 -0
  24. package/types/js/figure/DrawContext2D.d.ts +9 -0
  25. package/types/js/figure/DrawingObjects/DrawingObject.d.ts +45 -0
  26. package/types/js/figure/DrawingObjects/GLObject/GLObject.d.ts +146 -0
  27. package/types/js/figure/DrawingObjects/HTMLObject/HTMLObject.d.ts +29 -0
  28. package/types/js/figure/DrawingObjects/TextObject/TextObject.d.ts +94 -0
  29. package/types/js/figure/DrawingObjects/TextObject/glyphMeasures.d.ts +7 -0
  30. package/types/js/figure/DrawingObjects/VertexObject/VertexGeneric.d.ts +21 -0
  31. package/types/js/figure/DrawingObjects/VertexObject/VertexObject.d.ts +0 -0
  32. package/types/js/figure/DrawingObjects/VertexObject/VertexText.d.ts +34 -0
  33. package/types/js/figure/Element.d.ts +1212 -0
  34. package/types/js/figure/Equation/Elements/BaseAnnotationFunction.d.ts +118 -0
  35. package/types/js/figure/Equation/Elements/BaseEquationFunction.d.ts +20 -0
  36. package/types/js/figure/Equation/Elements/Bounds.d.ts +49 -0
  37. package/types/js/figure/Equation/Elements/Color.d.ts +7 -0
  38. package/types/js/figure/Equation/Elements/Container.d.ts +5 -0
  39. package/types/js/figure/Equation/Elements/Element.d.ts +95 -0
  40. package/types/js/figure/Equation/Elements/Fraction.d.ts +5 -0
  41. package/types/js/figure/Equation/Elements/Lines.d.ts +5 -0
  42. package/types/js/figure/Equation/Elements/Matrix.d.ts +5 -0
  43. package/types/js/figure/Equation/Elements/Offset.d.ts +5 -0
  44. package/types/js/figure/Equation/Elements/Scale.d.ts +5 -0
  45. package/types/js/figure/Equation/Equation.d.ts +984 -0
  46. package/types/js/figure/Equation/EquationForm.d.ts +139 -0
  47. package/types/js/figure/Equation/EquationFunctions.d.ts +3367 -0
  48. package/types/js/figure/Equation/EquationSymbols.d.ts +1646 -0
  49. package/types/js/figure/Equation/HTMLEquation.d.ts +56 -0
  50. package/types/js/figure/Equation/Symbols/AngleBracket.d.ts +6 -0
  51. package/types/js/figure/Equation/Symbols/Arrow.d.ts +17 -0
  52. package/types/js/figure/Equation/Symbols/Bar.d.ts +6 -0
  53. package/types/js/figure/Equation/Symbols/Box.d.ts +11 -0
  54. package/types/js/figure/Equation/Symbols/Brace.d.ts +6 -0
  55. package/types/js/figure/Equation/Symbols/Bracket.d.ts +8 -0
  56. package/types/js/figure/Equation/Symbols/Division.d.ts +8 -0
  57. package/types/js/figure/Equation/Symbols/Integral.d.ts +7 -0
  58. package/types/js/figure/Equation/Symbols/Line.d.ts +5 -0
  59. package/types/js/figure/Equation/Symbols/Product.d.ts +6 -0
  60. package/types/js/figure/Equation/Symbols/Radical.d.ts +9 -0
  61. package/types/js/figure/Equation/Symbols/SquareBracket.d.ts +6 -0
  62. package/types/js/figure/Equation/Symbols/Strike.d.ts +8 -0
  63. package/types/js/figure/Equation/Symbols/Sum.d.ts +6 -0
  64. package/types/js/figure/Equation/Symbols/SymbolNew.d.ts +15 -0
  65. package/types/js/figure/Equation/Symbols/Vinculum.d.ts +6 -0
  66. package/types/js/figure/Figure.d.ts +711 -0
  67. package/types/js/figure/FigureCollections/Angle.d.ts +766 -0
  68. package/types/js/figure/FigureCollections/Axis.d.ts +517 -0
  69. package/types/js/figure/FigureCollections/Axis3.d.ts +118 -0
  70. package/types/js/figure/FigureCollections/Button.d.ts +195 -0
  71. package/types/js/figure/FigureCollections/EquationLabel.d.ts +77 -0
  72. package/types/js/figure/FigureCollections/FigureCollections.d.ts +122 -0
  73. package/types/js/figure/FigureCollections/Legend.d.ts +270 -0
  74. package/types/js/figure/FigureCollections/Line.d.ts +587 -0
  75. package/types/js/figure/FigureCollections/Plot.d.ts +558 -0
  76. package/types/js/figure/FigureCollections/PolyLine.d.ts +487 -0
  77. package/types/js/figure/FigureCollections/Rectangle.d.ts +235 -0
  78. package/types/js/figure/FigureCollections/SlideNavigator.d.ts +255 -0
  79. package/types/js/figure/FigureCollections/Slider.d.ts +155 -0
  80. package/types/js/figure/FigureCollections/Text.d.ts +307 -0
  81. package/types/js/figure/FigureCollections/Toggle.d.ts +185 -0
  82. package/types/js/figure/FigureCollections/Trace.d.ts +237 -0
  83. package/types/js/figure/FigurePrimitives/FigureElementPrimitive2DText.d.ts +119 -0
  84. package/types/js/figure/FigurePrimitives/FigureElementPrimitiveGLText.d.ts +94 -0
  85. package/types/js/figure/FigurePrimitives/FigureElementPrimitiveGesture.d.ts +536 -0
  86. package/types/js/figure/FigurePrimitives/FigureElementPrimitiveMorph.d.ts +175 -0
  87. package/types/js/figure/FigurePrimitives/FigurePrimitiveTypes.d.ts +788 -0
  88. package/types/js/figure/FigurePrimitives/FigurePrimitiveTypes2D.d.ts +1324 -0
  89. package/types/js/figure/FigurePrimitives/FigurePrimitiveTypes3D.d.ts +1105 -0
  90. package/types/js/figure/FigurePrimitives/FigurePrimitives.d.ts +173 -0
  91. package/types/js/figure/FigurePrimitives/Generic.d.ts +5 -0
  92. package/types/js/figure/FigurePrimitives/Text.d.ts +17 -0
  93. package/types/js/figure/FontManager.d.ts +113 -0
  94. package/types/js/figure/Gesture.d.ts +39 -0
  95. package/types/js/figure/Recorder/Recorder.d.ts +291 -0
  96. package/types/js/figure/Recorder/parseState.d.ts +3 -0
  97. package/types/js/figure/Recorder/recorder.worker.d.ts +1 -0
  98. package/types/js/figure/Recorder/state.d.ts +7 -0
  99. package/types/js/figure/SlideNavigator.d.ts +606 -0
  100. package/types/js/figure/TimeKeeper.d.ts +174 -0
  101. package/types/js/figure/geometries/arc.d.ts +18 -0
  102. package/types/js/figure/geometries/arrow.d.ts +215 -0
  103. package/types/js/figure/geometries/buffer.d.ts +4 -0
  104. package/types/js/figure/geometries/copy/copy.d.ts +178 -0
  105. package/types/js/figure/geometries/ellipse.d.ts +17 -0
  106. package/types/js/figure/geometries/line.d.ts +13 -0
  107. package/types/js/figure/geometries/lines/corners.d.ts +7 -0
  108. package/types/js/figure/geometries/lines/dashes.d.ts +23 -0
  109. package/types/js/figure/geometries/lines/lines.d.ts +31 -0
  110. package/types/js/figure/geometries/polygon/polygon.d.ts +12 -0
  111. package/types/js/figure/geometries/rectangle.d.ts +19 -0
  112. package/types/js/figure/geometries/triangle.d.ts +27 -0
  113. package/types/js/figure/webgl/Atlas.d.ts +42 -0
  114. package/types/js/figure/webgl/shaders.d.ts +143 -0
  115. package/types/js/figure/webgl/target.d.ts +9 -0
  116. package/types/js/figure/webgl/webgl.d.ts +54 -0
  117. package/types/js/tools/FunctionMap.d.ts +69 -0
  118. package/types/js/tools/color.d.ts +11 -0
  119. package/types/js/tools/colorNames.d.ts +2 -0
  120. package/types/js/tools/d2/polygon.d.ts +60 -0
  121. package/types/js/tools/d2/triangles.d.ts +0 -0
  122. package/types/js/tools/d3/cone.d.ts +57 -0
  123. package/types/js/tools/d3/cube.d.ts +26 -0
  124. package/types/js/tools/d3/cylinder.d.ts +45 -0
  125. package/types/js/tools/d3/line3.d.ts +55 -0
  126. package/types/js/tools/d3/prism.d.ts +49 -0
  127. package/types/js/tools/d3/revolve.d.ts +87 -0
  128. package/types/js/tools/d3/sphere.d.ts +33 -0
  129. package/types/js/tools/d3/surface.d.ts +47 -0
  130. package/types/js/tools/g2.d.ts +242 -0
  131. package/types/js/tools/geometry/Bounds.d.ts +446 -0
  132. package/types/js/tools/geometry/Line.d.ts +314 -0
  133. package/types/js/tools/geometry/Path.d.ts +67 -0
  134. package/types/js/tools/geometry/Plane.d.ts +201 -0
  135. package/types/js/tools/geometry/Point.d.ts +359 -0
  136. package/types/js/tools/geometry/Rect.d.ts +115 -0
  137. package/types/js/tools/geometry/Transform.d.ts +623 -0
  138. package/types/js/tools/geometry/angle.d.ts +105 -0
  139. package/types/js/tools/geometry/common.d.ts +9 -0
  140. package/types/js/tools/geometry/coordinates.d.ts +30 -0
  141. package/types/js/tools/geometry/deceleration.d.ts +13 -0
  142. package/types/js/tools/geometry/polygon.d.ts +4 -0
  143. package/types/js/tools/geometry/quaternion.d.ts +15 -0
  144. package/types/js/tools/geometry/scene.d.ts +282 -0
  145. package/types/js/tools/geometry/tools.d.ts +8 -0
  146. package/types/js/tools/geometry/types.d.ts +2 -0
  147. package/types/js/tools/getCssColors.d.ts +1 -0
  148. package/types/js/tools/getCssVariables.d.ts +4 -0
  149. package/types/js/tools/getImageData.d.ts +1 -0
  150. package/types/js/tools/getScssColors.d.ts +2 -0
  151. package/types/js/tools/htmlGenerator.d.ts +85 -0
  152. package/types/js/tools/m2.d.ts +24 -0
  153. package/types/js/tools/m3.d.ts +71 -0
  154. package/types/js/tools/math.d.ts +112 -0
  155. package/types/js/tools/morph.d.ts +651 -0
  156. package/types/js/tools/styleSheets.d.ts +3 -0
  157. package/types/js/tools/tools.d.ts +281 -0
  158. package/types/js/tools/types.d.ts +305 -0
  159. package/figureone.worker.js +0 -1
@@ -0,0 +1,1105 @@
1
+ import type { TypeGLBufferUsage } from '../DrawingObjects/GLObject/GLObject';
2
+ import type { CPY_Step } from '../geometries/copy/copy';
3
+ import type { TypeParsablePoint } from '../../tools/geometry/Point';
4
+ import type Scene from '../../tools/geometry/scene';
5
+ import type { TypeColor } from '../../tools/types';
6
+ import type { TypeParsableLine } from '../../tools/geometry/Line';
7
+ import type { OBJ_Line3Arrow } from '../../tools/d3/line3';
8
+ import type { OBJ_Texture, OBJ_FigurePrimitive } from './FigurePrimitiveTypes';
9
+ /**
10
+ * @property {'directional' | 'point' | null} [light] the scene light that will
11
+ * be cast on the shape. Use `null` for no lighting - all surfaces will have
12
+ * the defined color. (`'directional'`)
13
+ * @property {Array<CPY_Step | string> | CPY_Step} [copy] Create copies the
14
+ * shapes vertices to replicate the shape in space. Copies of normals, colors
15
+ * (if defined) and texture coordinates (if defined) will also be made.
16
+ * @property {TypeGLBufferUsage} [usage] use `'DYNAMIC'` if the shape's vertices
17
+ * will be updated very frequently (`'STATIC'`)
18
+ * @interface
19
+ * @group 3D Shape Primitives
20
+ */
21
+ export type OBJ_Generic3All = {
22
+ light?: 'directional' | 'point' | 'ambient' | null;
23
+ copy?: Array<CPY_Step | string> | CPY_Step;
24
+ usage?: TypeGLBufferUsage;
25
+ touchScale?: number | TypeParsablePoint;
26
+ };
27
+ /**
28
+ * Options object for a {@link FigureElementPrimitive} of a generic 3D shape.
29
+ * Extends {@link OBJ_Generic3All} and {@link OBJ_FigurePrimitive}
30
+ *
31
+ * ![](./apiassets/generic3.png)
32
+ *
33
+ * ![](./apiassets/generic3.gif)
34
+ *
35
+ * {@link OBJ_GenericGL} can be used for shape creation with custom shaders.
36
+ *
37
+ * But for many custom shapes, only points and normals of the shape need to be
38
+ * defined, without needing to customize the shaders.
39
+ *
40
+ * {@link OBJ_Generic3} Provides the ability to create many custom shapes that
41
+ * don't need shader customization.
42
+ *
43
+ * @property {'TRIANGLES' | 'POINTS' | 'FAN' | 'STRIP' | 'LINES'} [glPrimitive]
44
+ * (`'TRIANGLES'`)
45
+ * @property {Array<TypeParsablePoint>} [points] positions of vertices of shape
46
+ * @property {Array<TypeParsablePoint>} [normals] normals for each vertex
47
+ * @property {Array<TypeColor>} [colors] define a color for each vertex if the
48
+ * shape will be more than just a single color. Otherwise use `color` if a
49
+ * single color.
50
+ * @property {OBJ_Texture} [texture] use to overlay a texture onto the shape's
51
+ * surfaces
52
+ *
53
+ * @see To test examples, append them to the
54
+ * <a href="#shapes3d-boilerplate">boilerplate</a>
55
+ *
56
+ * @example
57
+ * // Cubes with texture on each face
58
+ * figure.scene.setProjection({ style: 'orthographic' });
59
+ * figure.scene.setCamera({ position: [1, 1, 2] });
60
+ * figure.scene.setLight({ directional: [0.7, 0.5, 1] });
61
+ *
62
+ * const [points, normals] = Fig.cube({ side: 0.8 });
63
+ *
64
+ * figure.add({
65
+ * make: 'generic3',
66
+ * points,
67
+ * normals,
68
+ * texture: {
69
+ * src: './flowers.jpeg',
70
+ * coords: [
71
+ * 0, 0, 0.333, 0, 0.333, 0.5,
72
+ * 0, 0, 0.333, 0.5, 0, 0.5,
73
+ * 0.333, 0, 0.666, 0, 0.666, 0.5,
74
+ * 0.333, 0, 0.666, 0.5, 0.333, 0.5,
75
+ * 0.666, 0, 1, 0, 1, 0.5,
76
+ * 0.666, 0, 1, 0.5, 0.666, 0.5,
77
+ * 0, 0.5, 0.333, 1, 0, 1,
78
+ * 0, 0.5, 0.333, 0.5, 0.333, 1,
79
+ * 0.333, 0.5, 0.666, 1, 0.333, 1,
80
+ * 0.333, 0.5, 0.666, 0.5, 0.666, 1,
81
+ * 0.666, 0.5, 1, 1, 0.666, 1,
82
+ * 0.666, 0.5, 1, 0.5, 1, 1,
83
+ * ],
84
+ * loadColor: [0, 0, 0, 0],
85
+ * },
86
+ * });
87
+ *
88
+ * @example
89
+ * // Create a a ring around a sphere.
90
+ * figure.scene.setProjection({ style: 'orthographic' });
91
+ * figure.scene.setCamera({ position: [1, 1, 2] });
92
+ * figure.scene.setLight({ directional: [0.7, 0.5, 1] });
93
+ * const { sphere, polygon, revolve } = Fig;
94
+ * const [spherePoints, sphereNormals] = sphere({ radius: 0.15 });
95
+ * // The ring is a flattened doughnut
96
+ * const [ringPoints, ringNormals] = revolve({
97
+ * profile: polygon({
98
+ * close: true,
99
+ * sides: 20,
100
+ * radius: 0.05,
101
+ * center: [0, 0.3],
102
+ * direction: -1,
103
+ * transform: ['s', 0.1, 1, 1],
104
+ * }),
105
+ * normals: 'curve',
106
+ * sides: 50,
107
+ * transform: ['d', 0, 1, 0],
108
+ * });
109
+ * const a = figure.add({
110
+ * make: 'generic3',
111
+ * points: [...spherePoints, ...ringPoints],
112
+ * normals: [...sphereNormals, ...ringNormals],
113
+ * color: [1, 0, 0, 1],
114
+ * transform: [['r', 0.15, 1, 0, 0], ['r', 0.3, 0, 1, 0]],
115
+ * });
116
+ * // Animate the shape to slowly rotate around the x and y axes
117
+ * a.animations.new()
118
+ * .custom({
119
+ * callback: (t) => {
120
+ * a.transform.updateRotation(t * 0.15);
121
+ * a.transform.updateRotation(t * 0.3, null, 1);
122
+ * },
123
+ * duration: null,
124
+ * })
125
+ * .start();
126
+ * @interface
127
+ * @group 3D Shape Primitives
128
+ */
129
+ export type OBJ_Generic3 = {
130
+ glPrimitive?: 'TRIANGLES' | 'POINTS' | 'FAN' | 'STRIP' | 'LINES';
131
+ points?: Array<TypeParsablePoint>;
132
+ normals?: Array<TypeParsablePoint>;
133
+ colors?: Array<TypeColor>;
134
+ texture?: OBJ_Texture;
135
+ } & OBJ_Generic3All & OBJ_FigurePrimitive;
136
+ /**
137
+ * Sphere shape options object that extends {@link OBJ_Generic3All}
138
+ * and {@link OBJ_FigurePrimitive}
139
+ *
140
+ * ![](./apiassets/sphere.png)
141
+ *
142
+ * By default, a sphere with its center at the origin will be created.
143
+ *
144
+ * @property {number} [sides] number of sides around sphere's half great circle
145
+ * (`10`)
146
+ * @property {number} [radius] radius of sphere (`1`)
147
+ * @property {'curve' | 'flat'} [normals] `flat` normals will make light
148
+ * shading across a face cone constant. `curve` will gradiate the shading. Use
149
+ * `curve` to make a surface look more round with fewer number of sides.
150
+ * (`flat`)
151
+ * @property {TypeParsablePoint} [center] center position of sphere (`[0, 0]`)
152
+ * @property {boolean} [lines] if `true` then points representing
153
+ * the edes of the faces will be returned. If `false`, then points
154
+ * representing two triangles per face and an
155
+ * associated normal for each point will be returned.
156
+ *
157
+ * @see To test examples, append them to the
158
+ * <a href="#shapes3d-boilerplate">boilerplate</a>
159
+ *
160
+ * @example
161
+ * figure.add({
162
+ * make: 'sphere',
163
+ * radius: 0.5,
164
+ * color: [1, 0, 0, 1],
165
+ * });
166
+ *
167
+ * @example
168
+ * // Sphere with 'curve' normals
169
+ * figure.add({
170
+ * make: 'sphere',
171
+ * radius: 0.5,
172
+ * normals: 'curve',
173
+ * color: [1, 0, 0, 1],
174
+ * });
175
+ *
176
+ * @example
177
+ * // Wire mesh sphere
178
+ * figure.add({
179
+ * make: 'sphere',
180
+ * radius: 0.5,
181
+ * sides: 30,
182
+ * lines: true,
183
+ * normals: 'curve',
184
+ * color: [1, 0, 0, 1],
185
+ * });
186
+ *
187
+ * @example
188
+ * // Ring of spheres, rotated to by in xz plane
189
+ * figure.add({
190
+ * make: 'sphere',
191
+ * radius: 0.1,
192
+ * color: [1, 0, 0, 1],
193
+ * center: [0.3, 0, 0],
194
+ * normals: 'curve',
195
+ * copy: [
196
+ * { along: 'rotation', num: 10, step: Math.PI * 2 / 10 },
197
+ * ],
198
+ * transform: ['r', Math.PI / 2, 1, 0, 0],
199
+ * });
200
+ * @interface
201
+ * @group 3D Shape Primitives
202
+ */
203
+ export type OBJ_Sphere = {
204
+ sides?: number;
205
+ radius?: number;
206
+ normals?: 'curve' | 'flat';
207
+ center?: TypeParsablePoint;
208
+ lines?: boolean;
209
+ } & OBJ_Generic3All & OBJ_FigurePrimitive;
210
+ /**
211
+ * Cube shape options object that extends {@link OBJ_Generic3All}
212
+ * and {@link OBJ_FigurePrimitive}
213
+ *
214
+ * ![](./apiassets/cube.png)
215
+ *
216
+ * By default, a cube will be constructed around the origin, with the xyz axes
217
+ * being normal to the cube faces.
218
+ *
219
+ * @property {number} [side] side length (`1`)
220
+ * @property {TypeParsablePoint} [center] center point (`[0, 0]`)
221
+ * points of cube
222
+ * @property {boolean} [lines] if `true` then points representing
223
+ * the 12 edges of the cube will be returned. If `false`, then points
224
+ * representing two triangles per face (12 triangles, 36 points) and an
225
+ * associated normal for each point will be returned. (`false`)
226
+ *
227
+ * @see To test examples, append them to the
228
+ * <a href="#shapes3d-boilerplate">boilerplate</a>
229
+ *
230
+ * @example
231
+ * figure.add({
232
+ * make: 'cube',
233
+ * side: 0.5,
234
+ * color: [1, 0, 0, 1],
235
+ * });
236
+ *
237
+ *
238
+ * @example
239
+ * // 3x3 grid of cubes
240
+ * figure.add({
241
+ * make: 'cube',
242
+ * side: 0.2,
243
+ * color: [1, 0, 0, 1],
244
+ * copy: [
245
+ * { along: 'x', num: 2, step: 0.22 },
246
+ * { along: 'y', num: 2, step: 0.22 },
247
+ * { along: 'z', num: 2, step: 0.22 },
248
+ * ],
249
+ * });
250
+ *
251
+ * @example
252
+ * // Wire mesh cube
253
+ * figure.add({
254
+ * make: 'cube',
255
+ * side: 0.5,
256
+ * lines: true,
257
+ * color: [1, 0, 0, 1],
258
+ * });
259
+ * @interface
260
+ * @group 3D Shape Primitives
261
+ */
262
+ export type OBJ_Cube = {
263
+ side?: number;
264
+ center?: TypeParsablePoint;
265
+ lines?: boolean;
266
+ } & OBJ_FigurePrimitive & OBJ_Generic3All;
267
+ /**
268
+ * Cylinder shape options object that extends {@link OBJ_Generic3All}
269
+ * and {@link OBJ_FigurePrimitive}
270
+ *
271
+ * ![](./apiassets/cylinder.png)
272
+ *
273
+ * By default, a cylinder along the x axis will be created.
274
+ *
275
+ * @property {number} [sides] number of cylinder sides (`10`)
276
+ * @property {number} [radius] radius of cylinder (`1`)
277
+ * @property {'curve' | 'flat'} [normals] `flat` normals will make
278
+ * shading (from light source) across a face cone constant.
279
+ * `curve` will gradiate the shading. Use `curve` to make a surface look more
280
+ * round with fewer number of sides. (`flat`)
281
+ * @property {TypeParsableLine} [line] line that can position and
282
+ * orient the cylinder. First point of line is cylinder base center, and second
283
+ * point is the top center.
284
+ * @property {number} [length] length of the cylinder if `line` isn't
285
+ * defined (`1`)
286
+ * @property {boolean | 1 | 2} [ends] `true` fills both ends of the cylinder.
287
+ * `false` does not fill ends. `1` fills only the first end. `2` fills only the
288
+ * the second end. (`true`)
289
+ * @property {number} [rotation] rotation of base - this is only noticable for
290
+ * small numbers of sides (`0`)
291
+ * points of cube
292
+ * @property {boolean} [lines] if `true` then points representing
293
+ * the edes of the faces will be returned. If `false`, then points
294
+ * representing two triangles per face and an
295
+ * associated normal for each point will be returned.
296
+ *
297
+ * @see To test examples, append them to the
298
+ * <a href="#shapes3d-boilerplate">boilerplate</a>
299
+ *
300
+ * @example
301
+ * figure.add({
302
+ * make: 'cylinder',
303
+ * radius: 0.2,
304
+ * length: 0.5,
305
+ * sides: 20,
306
+ * color: [1, 0, 0, 1],
307
+ * });
308
+ *
309
+ *
310
+ * @example
311
+ * // Use curve normals to give rounder looks for same number of sides
312
+ * figure.add({
313
+ * make: 'cylinder',
314
+ * radius: 0.2,
315
+ * length: 0.5,
316
+ * sides: 20,
317
+ * normals: 'curve',
318
+ * color: [1, 0, 0, 1],
319
+ * });
320
+ *
321
+ * @example
322
+ * // Wire mesh cylinder
323
+ * figure.add({
324
+ * make: 'cylinder',
325
+ * radius: 0.2,
326
+ * length: 0.2,
327
+ * lines: true,
328
+ * sides: 50,
329
+ * ends: false,
330
+ * color: [1, 0, 0, 1],
331
+ * });
332
+ *
333
+ * @example
334
+ * // Three cylinders as x, y, z axes
335
+ * figure.add([
336
+ * {
337
+ * make: 'cylinder',
338
+ * radius: 0.02,
339
+ * line: [[0, 0, 0], [0.5, 0, 0]],
340
+ * color: [1, 0, 0, 1],
341
+ * },
342
+ * {
343
+ * make: 'cylinder',
344
+ * radius: 0.02,
345
+ * line: [[0, 0, 0], [0, 0.5, 0]],
346
+ * color: [0, 1, 0, 1],
347
+ * },
348
+ * {
349
+ * make: 'cylinder',
350
+ * radius: 0.02,
351
+ * line: [[0, 0, 0], [0, 0, 0.5]],
352
+ * color: [0, 0, 1, 1],
353
+ * },
354
+ * ]);
355
+ * @interface
356
+ * @group 3D Shape Primitives
357
+ */
358
+ export type OBJ_Cylinder = {
359
+ sides?: number;
360
+ radius?: number;
361
+ normals?: 'curve' | 'flat';
362
+ line?: TypeParsableLine;
363
+ length?: number;
364
+ ends?: boolean | 1 | 2;
365
+ rotation?: number;
366
+ } & OBJ_FigurePrimitive & OBJ_Generic3All;
367
+ /**
368
+ * 3D Line options object that extends {@link OBJ_Generic3All}
369
+ * and {@link OBJ_FigurePrimitive}
370
+ *
371
+ * ![](./apiassets/line3.png)
372
+ *
373
+ * A 3D line is a cylinder with optional arrows on the end. Unlike a 2D line,
374
+ * the arrow profiles can only be simple triangles.
375
+ *
376
+ * @property {TypeParsablePoint} [p1] (`[0, 0, 0]`)
377
+ * @property {TypeParsablePoint} [p2] (default: `p1 + [1, 0, 0]`)
378
+ * @property {number} [width] width of line
379
+ * @property {OBJ_Line3Arrow | boolean} [arrow] define to use arrows at one or both ends
380
+ * of the line
381
+ * @property {number} [sides] number of sides (`10`)
382
+ * @property {'curve' | 'flat'} [normals] `flat` normals will make light
383
+ * shading across a line face constant. `curve` will gradiate the shading. Use
384
+ * `curve` to make a surface look more round with fewer number of sides.
385
+ * (`curve`)
386
+ * @property {number} [rotation] rotation of line around its axis - this is
387
+ * only noticable for small numbers of sides (`0`)
388
+ * @property {boolean} [lines] if `true` then points representing
389
+ * the edes of the faces will be returned. If `false`, then points
390
+ * representing two triangles per face and an
391
+ * associated normal for each point will be returned.
392
+ *
393
+ * @see To test examples, append them to the
394
+ * <a href="#shapes3d-boilerplate">boilerplate</a>
395
+ *
396
+ * @example
397
+ * // Simple line
398
+ * figure.add({
399
+ * make: 'line3',
400
+ * p1: [0, 0, 0],
401
+ * p2: [0, 1, 0],
402
+ * color: [1, 0, 0, 1],
403
+ * });
404
+ *
405
+ *
406
+ * @example
407
+ * // Thick line with arrows on both ends
408
+ * figure.add({
409
+ * make: 'line3',
410
+ * p1: [0, 0, 0],
411
+ * p2: [0, 1, 0],
412
+ * arrow: { ends: 'all', width: 0.1, length: 0.1 },
413
+ * sides: 30,
414
+ * width: 0.05,
415
+ * color: [1, 0, 0, 1],
416
+ * });
417
+ *
418
+ * @example
419
+ * // Wire mesh line with arrow
420
+ * figure.add({
421
+ * make: 'line3',
422
+ * p1: [0, 0, 0],
423
+ * p2: [0, 1, 0],
424
+ * arrow: { ends: 'end' },
425
+ * color: [1, 0, 0, 1],
426
+ * lines: true,
427
+ * });
428
+ *
429
+ * @example
430
+ * // Ball of arrows
431
+ * figure.add(
432
+ * {
433
+ * make: 'line3',
434
+ * p1: [0, 0, 0],
435
+ * p2: [0, 0.4, 0],
436
+ * color: [1, 0, 0, 1],
437
+ * width: 0.01,
438
+ * arrow: { end: 'end', width: 0.02 },
439
+ * copy: [
440
+ * { along: 'rotation', num: 20, step: Math.PI * 2 / 20 },
441
+ * { along: 'rotation', axis: [0, 1, 0], num: 20, step: Math.PI * 2 / 20 },
442
+ * ],
443
+ * },
444
+ * );
445
+ * @interface
446
+ * @group 3D Shape Primitives
447
+ */
448
+ export type OBJ_Line3 = {
449
+ sides?: number;
450
+ p1?: TypeParsablePoint;
451
+ p2?: TypeParsablePoint;
452
+ width?: number;
453
+ arrow?: OBJ_Line3Arrow;
454
+ rotation?: number;
455
+ normals?: 'curve' | 'flat';
456
+ } & OBJ_FigurePrimitive & OBJ_Generic3All;
457
+ /**
458
+ * Cone shape options object that extends {@link OBJ_Generic3All}
459
+ * and {@link OBJ_FigurePrimitive}
460
+ *
461
+ * ![](./apiassets/cone.png)
462
+ *
463
+ * By default, a cone with its base at the origin and its tip along the x axis
464
+ * will be created.
465
+ *
466
+ * @property {number} [sides] number of sides (`10`)
467
+ * @property {number} [radius] radius of cube base
468
+ * @property {'curve' | 'flat'} [normals] `flat` normals will make light
469
+ * shading across a face cone constant. `curve` will gradiate the shading. Use
470
+ * `curve` to make a surface look more round with fewer number of sides.
471
+ * (`flat`)
472
+ * @property {TypeParsableLine} [line] line that can position and
473
+ * orient the cone. First point of line is cone base center, and second point
474
+ * is cone tip.
475
+ * @property {number} [length] length of the cone along the x axis if
476
+ * `line` isn't defined (`1`)
477
+ * @property {number} [rotation] rotation of base - this is only noticable for
478
+ * small numbers of sides (`0`)
479
+ * points of cube
480
+ * @property {boolean} [lines] if `true` then points representing
481
+ * the edes of the faces will be returned. If `false`, then points
482
+ * representing two triangles per face and an
483
+ * associated normal for each point will be returned.
484
+ *
485
+ * @see To test examples, append them to the
486
+ * <a href="#shapes3d-boilerplate">boilerplate</a>
487
+ *
488
+ * @example
489
+ * figure.add({
490
+ * make: 'cone',
491
+ * radius: 0.2,
492
+ * sides: 20,
493
+ * color: [1, 0, 0, 1],
494
+ * line: [[0, 0, 0], [0, 0.5, 0]],
495
+ * });
496
+ *
497
+ * @example
498
+ * // Cone with curve normals
499
+ * figure.add({
500
+ * make: 'cone',
501
+ * radius: 0.2,
502
+ * normals: 'curve',
503
+ * sides: 20,
504
+ * color: [1, 0, 0, 1],
505
+ * line: [[0, 0, 0], [0, 0.5, 0]],
506
+ * });
507
+ *
508
+ * @example
509
+ * // Wire mesh cone
510
+ * figure.add({
511
+ * make: 'cone',
512
+ * radius: 0.2,
513
+ * normals: 'curve',
514
+ * sides: 20,
515
+ * color: [1, 0, 0, 1],
516
+ * line: [[0, 0, 0], [0, 0.5, 0]],
517
+ * lines: true,
518
+ * });
519
+ * @interface
520
+ * @group 3D Shape Primitives
521
+ */
522
+ export type OBJ_Cone = {
523
+ sides?: number;
524
+ radius?: number;
525
+ normals?: 'curve' | 'flat';
526
+ line?: TypeParsableLine;
527
+ length?: number;
528
+ rotation?: number;
529
+ lines?: boolean;
530
+ } & OBJ_FigurePrimitive & OBJ_Generic3All;
531
+ /**
532
+ * Prism shape options object that extends {@link OBJ_Generic3All}
533
+ * and {@link OBJ_FigurePrimitive}
534
+ *
535
+ * ![](./apiassets/prism.png)
536
+ *
537
+ * A prism base is defined in the XY plane, and it's length extends
538
+ * into +z. Use `transform` to orient it in any other way.
539
+ *
540
+ * Triangles will be created for the ends if the base is convex. If the base
541
+ * is not convex, use `baseTriangles` to define the triangles.
542
+ *
543
+ * @property {number} [base] base border points defined in the XY plane - the
544
+ * points should be defined in the counter-clock-wise direction.
545
+ * @property {Array<TypeParsablePoint>} baseTriangles triangles in the XY plane
546
+ * that create the base fill. If the base is convex, then the triangles can be
547
+ * auto-generated and this property left undefined.
548
+ * @property {number} [length] length of the prism
549
+ * @property {boolean} [lines] if `true` then points representing
550
+ * the edges of the prism will be returned. If `false`, then points
551
+ * representing triangle faces and associated normals will be returned.
552
+ * (`false`)
553
+ *
554
+ * @see To test examples, append them to the
555
+ * <a href="#shapes3d-boilerplate">boilerplate</a>
556
+ *
557
+ * @example
558
+ * // Create a rectangular prism
559
+ * figure.add(
560
+ * {
561
+ * make: 'prism',
562
+ * base: [[0, 0], [0.5, 0], [0.5, 0.2], [0, 0.2]],
563
+ * color: [1, 0, 0, 1],
564
+ * },
565
+ * );
566
+ *
567
+ * @example
568
+ * // Create a hexagonal prism along the x axis with lines
569
+ * figure.add(
570
+ * {
571
+ * make: 'prism',
572
+ * base: Fig.polygon({ radius: 0.1, sides: 6 }),
573
+ * color: [1, 0, 0, 1],
574
+ * transform: ['r', Math.PI / 2, 0, 1, 0],
575
+ * lines: true,
576
+ * },
577
+ * );
578
+ *
579
+ * @example
580
+ * // Create a bow tie prism defining the base triangles
581
+ * figure.add(
582
+ * {
583
+ * make: 'prism',
584
+ * base: [[0, 0], [0.25, 0.1], [0.5, 0], [0.5, 0.3], [0.25, 0.2], [0, 0.3]],
585
+ * baseTriangles: [
586
+ * [0, 0], [0.25, 0.1], [0.25, 0.2],
587
+ * [0, 0], [0.25, 0.2], [0, 0.3],
588
+ * [0.25, 0.1], [0.5, 0], [0.5, 0.3],
589
+ * [0.25, 0.1], [0.5, 0.3], [0.25, 0.2],
590
+ * ],
591
+ * color: [1, 0, 0, 1],
592
+ * transform: ['r', Math.PI / 2, 0, 1, 0],
593
+ * },
594
+ * );
595
+ * @interface
596
+ * @group 3D Shape Primitives
597
+ */
598
+ export type OBJ_Prism = {
599
+ base?: Array<TypeParsablePoint>;
600
+ baseTriangles?: Array<TypeParsablePoint>;
601
+ length?: number;
602
+ lines?: boolean;
603
+ } & OBJ_FigurePrimitive & OBJ_Generic3All;
604
+ /**
605
+ * Revolve shape options object that extends {@link OBJ_Generic3All}
606
+ * and {@link OBJ_FigurePrimitive}.
607
+ *
608
+ * ![](./apiassets/revolve.png)
609
+ *
610
+ * Revolve (or radially sweep) a profile in the XY plane around the x axis to
611
+ * form a 3D surface. The profile y values must be greater than or equal to 0.
612
+ *
613
+ * Profiles can be open (start and end point are different) or closed (start
614
+ * and end point are equal).
615
+ *
616
+ * For predictable lighting results, profiles should be created with the
617
+ * following rules:
618
+ *
619
+ * - An open profile's start points should have an x value less than its end
620
+ * point
621
+ * - Closed profiles where all points have y > 0 should be defined in the
622
+ * clockwise direction when looking at the XY plane from the +z axis.
623
+ *
624
+ * If an open profile's start and ends points are at y = 0, then the final shape
625
+ * will look solid.
626
+ *
627
+ * If an open profile's start and/or ends points have y > 0, then the final
628
+ * shape will look like a surface open at the ends with y > 0. As a surface can
629
+ * have only one color, then looking inside the shape the surface lighting will
630
+ * be opposite to that expected. To create open ended solids with lighting that
631
+ * is as expected, create the outside and inside surface with a closed profile.
632
+ *
633
+ * ![](./apiassets/revolveexplanation.png)
634
+ *
635
+ * @property {Array<TypeParsablePoint>} profile XY plane profile to be radially
636
+ * swept around the x axis
637
+ * @property {number} [sides] number of sides in the radial sweep
638
+ * @property {'flat' | 'curveRows' | 'curveRadial' | 'curve'} [normals]
639
+ * `flat` normals will make shading (from a light source) across a face of the
640
+ * object a constant color. `curveProfile` will gradiate the shading along the
641
+ * profile. `curveRadial` will gradiate the shading around the radial sweep.
642
+ * `curve` will gradiate the shading both around the radial sweep and along the
643
+ * profile. Use `curve`, `curveProfile`, or `curveRadial` to make a surface
644
+ * look more round with fewer number of sides.
645
+ * @property {number} [rotation] by default the profile will start in the XY
646
+ * plane and sweep around the x axis following the right hand rule. Use
647
+ * `rotation` to start the sweep at some angle where 0º is in the XY for +y and
648
+ * 90º is in the XZ plane for +z. initial angle of the revolve rotation
649
+ * @property {TypeParsablePoint} [axis] orient the draw space vertices of the
650
+ * shape so its axis is along this vector
651
+ * @property {boolean} [lines] if `true` then points representing
652
+ * the edes of the faces will be returned. If `false`, then points
653
+ * representing two triangles per face and an
654
+ * associated normal for each point will be returned.
655
+ *
656
+ * @see To test examples, append them to the
657
+ * <a href="#shapes3d-boilerplate">boilerplate</a>
658
+ *
659
+ * @example
660
+ * figure.add({
661
+ * make: 'revolve',
662
+ * profile: [[0, 0], [0, 0.05], [0.5, 0.05], [0.6, 0.1], [0.7, 0]],
663
+ * axis: [0, 1, 0],
664
+ * color: [1, 0, 0, 1],
665
+ * sides: 20,
666
+ * });
667
+ *
668
+ * @example
669
+ * // If creating a shell, then also create the inside surface as this will make
670
+ * // lighting more correct (note there is not shaddows).
671
+ * // Ensure to close the shell by adding the first point to the end of the
672
+ * // profile
673
+ * figure.add({
674
+ * make: 'revolve',
675
+ * profile: [[0, 0.15], [0.5, 0.3], [0.5, 0.29], [0, 0.14], [0, 0.15]],
676
+ * color: [1, 0, 0, 1],
677
+ * sides: 30,
678
+ * normals: 'curveRadial',
679
+ * });
680
+ *
681
+ * @example
682
+ * // Curvy vase like shape
683
+ * const x = Fig.range(0, 0.5, 0.01);
684
+ * const profile = x.map(_x => [_x, 0.1 + 0.05 * Math.sin(_x * 2 * Math.PI * 2)]);
685
+ * figure.add({
686
+ * make: 'revolve',
687
+ * profile: [...profile, [0.4, 0], [0, 0], [0, 0.1]],
688
+ * axis: [0, 1, 0],
689
+ * color: [1, 0, 0, 1],
690
+ * sides: 30,
691
+ * });
692
+ *
693
+ * @example
694
+ * // Make a torus by revolving a polygon around the axis. As the polygon is above
695
+ * // the x axis, a hole will be created
696
+ * // Try using `normals: 'curve'`, `normals: 'curveProfile'`, and
697
+ * // `normals: 'curveRadial'` to see different curve options.
698
+ * const { polygon } = Fig;
699
+ * figure.add({
700
+ * make: 'revolve',
701
+ * profile: polygon({
702
+ * radius: 0.1, center: [0, 0.3], sides: 20, direction: -1, close: true,
703
+ * }),
704
+ * color: [1, 0, 0, 1],
705
+ * sides: 30,
706
+ * });
707
+ *
708
+ * @example
709
+ * // Wire mesh arrow
710
+ * figure.add({
711
+ * make: 'revolve',
712
+ * profile: [[0, 0.03], [0.4, 0.03], [0.4, 0.09], [0.7, 0]],
713
+ * axis: [0, 1, 0],
714
+ * color: [1, 0, 0, 1],
715
+ * sides: 20,
716
+ * lines: true,
717
+ * });
718
+ *
719
+ * @example
720
+ * // Open profile y = 0 at ends
721
+ * figure.add({
722
+ * make: 'revolve',
723
+ * profile: [[0, 0], [0, 0.3], [0.5, 0.2], [1, 0.3], [1, 0]],
724
+ * color: [1, 0, 0, 1],
725
+ * sides: 30,
726
+ * });
727
+ *
728
+ * @example
729
+ * // Open profile y > 0 at ends
730
+ * figure.add({
731
+ * make: 'revolve',
732
+ * profile: [[0, 0.3], [0.5, 0.2], [1, 0.3]],
733
+ * color: [1, 0, 0, 1],
734
+ * sides: 30,
735
+ * });
736
+ *
737
+ * @example
738
+ * // Closed Profile
739
+ * figure.add({
740
+ * make: 'revolve',
741
+ * profile: [[0, 0.3], [0.5, 0.2], [1, 0.3], [1, 0.29], [0.5, 0.19], [0, 0.29], [0, 0.3]],
742
+ * color: [1, 0, 0, 1],
743
+ * sides: 30,
744
+ * });
745
+ * @interface
746
+ * @group 3D Shape Primitives
747
+ */
748
+ export type OBJ_Revolve = {
749
+ sides?: number;
750
+ profile?: Array<TypeParsablePoint>;
751
+ normals?: 'flat' | 'curveProfile' | 'curveRadial' | 'curve';
752
+ axis?: TypeParsablePoint;
753
+ rotation?: number;
754
+ lines?: boolean;
755
+ } & OBJ_FigurePrimitive & OBJ_Generic3All;
756
+ /**
757
+ * Surface shape options object that extends {@link OBJ_Generic3All}
758
+ * and {@link OBJ_FigurePrimitive}.
759
+ *
760
+ * ![](./apiassets/surface.png)
761
+ *
762
+ * ![](./apiassets/surfaceclosed.png)
763
+ *
764
+ * A surface is defined with a 2D matrix of points. Triangles that fill the
765
+ * surface are created between neighboring points in the matrix.
766
+ *
767
+ * If a surface is defined with 9 points (an array or arrays in JavaScript):
768
+ *
769
+ * ![](./apiassets/surfacematrix.png)
770
+ *
771
+ * Then triangles will be created between `adb`, `deb`, `bec`, `efc`, `dge`,
772
+ * `ghe`, `ehf`, and `hif`.
773
+ *
774
+ * The normal for triangle 'adb' is in the direction of the cross product
775
+ * of vector 'ad' with vector 'ab' (use the right hand rule where the fingers
776
+ * of the right hand curl from vector 'ad' to 'ab', and the thumb will then be
777
+ * the direction of the normal). Similarly, the normal of `hif` will be the
778
+ * direction of the cross product of `hi` with `hf`.
779
+ *
780
+ * Use the property `invertNormals` to make all the normals go in the reverse
781
+ * direction.
782
+ *
783
+ * A surface can be open or closed at the end rows or columns of the matrix.
784
+ * For example, a surface has closed columns if the first and last column
785
+ * of the matrix have identical points. A surface is has open rows if the first
786
+ * and last row of the matrix have different points.
787
+ *
788
+ * If using curved normals (`'curve'`, `'curveRows'` or `'curveColumns'`) with
789
+ * closed surfaces, use `closeRows` or `closeColumns` to ensure normal
790
+ * curvature is maintained at the end rows
791
+ * and columns.
792
+ *
793
+ * @property {Array<Array<TypeParsablePoint>>} [points] A grid of points that
794
+ * define a 3D surface
795
+ * @property {'curveColumns' | 'curveRows' | 'curve' | 'flat'} [normals]
796
+ * `flat` normals will make shading (from a light source) across a face of the
797
+ * object a constant color. `curveRows` will gradiate the shading along the
798
+ * rows of the grid. `curveColumns` will gradiate the shading along the columns
799
+ * of the grid. `curve` will gradiate the shading along both rows and columns.
800
+ * Use `curve`, `curveRows`, or `curveColumns` to make a surface
801
+ * look more round with fewer number of sides.
802
+ * @property {boolean} [closeRows] Set to `true` if first row and last row are
803
+ * the same, and normals is `'curveRows'` or `'curve'` to get correct normal
804
+ * calculations (`false`)
805
+ * @property {boolean} [closeColumns] Set to `true` if first row and last
806
+ * column are the same, and normals is `'curveColumns'` or `'curve'` to get
807
+ * correct normal calculations (`false`)
808
+ * shape
809
+ * @property {boolean} [lines] if `true` then points representing
810
+ * the edes of the faces will be returned. If `false`, then points
811
+ * representing two triangles per face and an
812
+ * associated normal for each point will be returned.
813
+ * @property {boolean} [invertNormals] if `true` then all normals will be
814
+ * inverted
815
+ *
816
+ * @see To test examples, append them to the
817
+ * <a href="#shapes3d-boilerplate">boilerplate</a>
818
+ *
819
+ * @example
820
+ * const points = Fig.surfaceGrid({
821
+ * x: [-0.8, 0.7, 0.03],
822
+ * y: [-0.8, 0.7, 0.03],
823
+ * z: x => 0.2 * Math.cos(x * 2 * Math.PI),
824
+ * });
825
+ * figure.scene.setCamera({ up: [0, 0, 1] });
826
+ * figure.add({
827
+ * make: 'surface',
828
+ * points,
829
+ * color: [1, 0, 0, 1],
830
+ * });
831
+ *
832
+ * @example
833
+ * // Surface wire mesh
834
+ * const points = Fig.surfaceGrid({
835
+ * x: [-0.8, 0.8, 0.03],
836
+ * y: [-0.8, 0.8, 0.03],
837
+ * z: (x, y) => y * 0.2 * Math.cos(x * 2 * Math.PI),
838
+ * });
839
+ * figure.scene.setCamera({ position: [-1, -1, 0.7], up: [0, 0, 1] });
840
+ * figure.add({
841
+ * make: 'surface',
842
+ * points,
843
+ * lines: true,
844
+ * color: [1, 0, 0, 1],
845
+ * });
846
+ *
847
+ * @example
848
+ * // Surface with wire mesh and fill
849
+ * const points = Fig.surfaceGrid({
850
+ * x: [-0.8, 0.8, 0.03],
851
+ * y: [-0.8, 0.8, 0.03],
852
+ * z: (x, y) => {
853
+ * const r = Math.sqrt(x * x + y * y) * Math.PI * 2 * 2;
854
+ * return Math.sin(r) / r;
855
+ * },
856
+ * });
857
+ * // Orient the camera so z is up
858
+ * figure.scene.setCamera({ up: [0, 0, 1] });
859
+ * figure.add({
860
+ * make: 'surface',
861
+ * points,
862
+ * color: [1, 0, 0, 1],
863
+ * });
864
+ * figure.add({
865
+ * make: 'surface',
866
+ * points,
867
+ * lines: true,
868
+ * color: [0, 0, 0, 1],
869
+ * });
870
+ *
871
+ * @example
872
+ * // Simple Closed surface around the x axis
873
+ * figure.add({
874
+ * make: 'surface',
875
+ * normals: 'curveColumns',
876
+ * closeRows: true,
877
+ * points: [
878
+ * [[0, 0, 0.5], [1, 0, 0.5]],
879
+ * [[0, -0.5, 0], [1, -0.5, 0]],
880
+ * [[0, 0, -0.5], [1, 0, -0.5]],
881
+ * [[0, 0.5, 0], [1, 0.5, 0]],
882
+ * [[0, 0, 0.5], [1, 0, 0.5]],
883
+ * ],
884
+ * color: [1, 0, 0, 1],
885
+ * });
886
+ *
887
+ * @example
888
+ * // Simple Closed surface around the x axis with curved normals
889
+ * figure.add({
890
+ * make: 'surface',
891
+ * normals: 'curveColumns',
892
+ * closeRows: true,
893
+ * points: [
894
+ * [[0, 0, 0.5], [1, 0, 0.5]],
895
+ * [[0, -0.5, 0], [1, -0.5, 0]],
896
+ * [[0, 0, -0.5], [1, 0, -0.5]],
897
+ * [[0, 0.5, 0], [1, 0.5, 0]],
898
+ * [[0, 0, 0.5], [1, 0, 0.5]],
899
+ * ],
900
+ * color: [1, 0, 0, 1],
901
+ * });
902
+ *
903
+ * @example
904
+ * // Create a matrix of points by taking a profile in XY and rotating
905
+ * // it around the x axis
906
+ * const { Point, Transform } = Fig;
907
+ * const points = [];
908
+ *
909
+ * // Rotation step
910
+ * const dr = Math.PI * 2 / 50;
911
+ * for (let r = 0; r < Math.PI * 2 + dr / 2; r += dr) {
912
+ * // Rotation matrix of rotation step around x axis
913
+ * const m = new Transform().rotate(r, 1, 0, 0).matrix();
914
+ *
915
+ * // A row of points is a profile rotated by some amount r
916
+ * points.push([]);
917
+ * // Make a profile for x values from 0 to 1
918
+ * for (let x = 0; x < 1; x += 0.05) {
919
+ * // The y coordinate of the profile changes with both x value, and
920
+ * // rotation value
921
+ * const y = 0.1 * Math.sin(6 * x) + 0.25 + 0.1 * Math.cos(3 * r);
922
+ * const p = new Point(x, y).transformBy(m);
923
+ * points[points.length - 1].push(p);
924
+ * }
925
+ * }
926
+ * figure.add({
927
+ * make: 'surface',
928
+ * points,
929
+ * color: [1, 0, 0, 1],
930
+ * });
931
+ * @interface
932
+ * @group 3D Shape Primitives
933
+ */
934
+ export type OBJ_Surface = {
935
+ points?: Array<Array<TypeParsablePoint>>;
936
+ normals?: 'curveColumns' | 'curveRows' | 'curve' | 'flat';
937
+ closeRows?: boolean;
938
+ closeColumns?: boolean;
939
+ lines?: boolean;
940
+ } & OBJ_FigurePrimitive & OBJ_Generic3All;
941
+ /**
942
+ * Camera control definition object that extends
943
+ * and {@link OBJ_FigurePrimitive}
944
+ *
945
+ * A camera control is a transparent rectangle that uses touch and drag
946
+ * gestures to rotate the position of the camera in a 3D scene around a vertical
947
+ * axis.
948
+ *
949
+ * The vertical axis will always remain vertical. Left/right movements will
950
+ * rotate the scene around the vertical axis (in the azimuth of the vertical
951
+ * axis), while up/down movements will change the elevation relative to the
952
+ * vertical axis.
953
+ *
954
+ * The transparent rectangle will be positioned relative to the 2D HTML canvas
955
+ * the figure is drawn in on the screen. The `left`, `bottom`, `width` and
956
+ * `height` properties are numbers from 0 to 1 which represent percentage of
957
+ * the screen width and height.
958
+ *
959
+ * Thus for the rectangle to cover the entire screen, values of `left: 0`,
960
+ * `bottom: 0`, `width: 1` and `height: 1` would be used (these are the default
961
+ * values as well).
962
+ *
963
+ * By default, the figure's {@link Scene} camera position is modified. If an
964
+ * element's custom scene is to be controlled, use the `scene` property to link
965
+ * to it.
966
+ *
967
+ * How fast the camera is rotated in the aziumuth and elevation is controlled by
968
+ * the `sensitivity`, `xSensitivity` and `ySensitivity` properties.
969
+ * A higher sensitivity value will result in more rotation for the same user
970
+ * movement. If only azimuthal or elevation rotation is desired set
971
+ * `ySensitivity` or `xSensitivity` to 0 respectively.
972
+ *
973
+ * @property {number} [left] screen left position to place the control
974
+ * rectangle. 0 is the left edge, while 1 is the right edge (`0`).
975
+ * @property {number} [bottom] screen bottom position to place the control
976
+ * rectangle. 0 is the bottom edge, while 1 is the top edge (`0`).
977
+ * @property {number} [width] width of control rectangle. 1 is the full
978
+ * width of the drawing canvas (`1`).
979
+ * @property {number} [height] height of control rectangle. 1 is the full
980
+ * height of the drawing canvas (`1`).
981
+ * @property {TypeParsablePoint} [axis] Axis to keep vertical as camera is
982
+ * rotated. The axis vector and scene.camera.up vector should be in the same
983
+ * plane (`[0, 1, 0]`)
984
+ * @property {Scene | string} [controlScene] Use this to control a scene that is not
985
+ * the default Figure scene.
986
+ * @property {number} [sensitivity] sensitivity of camera position relative to
987
+ * user movement where larger numbers result in more rotation for the same
988
+ * movement (`5`)
989
+ * @property {number} [xSensitivity] sensitivity to a horizontal user movement.
990
+ * Setting this to 0 will mean the scene doesn't not rotate aziumthally (`1`)
991
+ * @property {number} [ySensitivity] sensitivity to a vertical user movement.
992
+ * Setting this to 0 will mean the elevation does not change (`1`)
993
+ * @property {boolean} [back] if `true` then all 2D and 3D objects that can be
994
+ * touched will be touched before the camera control, regardless of where it is
995
+ * on the drawing stack. This should be used everytime 3D objects need priority
996
+ * over the camera control (`true`)
997
+ *
998
+ * @example
999
+ * // Add a camera control that will cover the whole screen
1000
+ *
1001
+ * figure.add([
1002
+ * {
1003
+ * make: 'cylinder',
1004
+ * radius: 0.01,
1005
+ * color: [1, 0, 0, 1],
1006
+ * line: [[-1, 0, 0], [1, 0, 0]],
1007
+ * },
1008
+ * {
1009
+ * make: 'cylinder',
1010
+ * radius: 0.01,
1011
+ * color: [0, 1, 0, 1],
1012
+ * line: [[0, -1, 0], [0, 1, 0]],
1013
+ * },
1014
+ * {
1015
+ * make: 'cylinder',
1016
+ * radius: 0.01,
1017
+ * color: [0, 0, 1, 1],
1018
+ * line: [[0, 0, -1], [0, 0, 1]],
1019
+ * },
1020
+ * {
1021
+ * make: 'grid',
1022
+ * bounds: [-0.8, -0.8, 1.6, 1.6],
1023
+ * xStep: 0.05,
1024
+ * yStep: 0.05,
1025
+ * line: { width: 0.002 },
1026
+ * color: [0.7, 0.7, 0.7, 1],
1027
+ * transform: ['r', Math.PI / 2, 1, 0, 0],
1028
+ * },
1029
+ * ]);
1030
+ *
1031
+ * // Add camera control
1032
+ * figure.add({
1033
+ * make: 'cameraControl',
1034
+ * });
1035
+ *
1036
+ * @example
1037
+ * // Add a thin bar at the bottom of the figure that rotates the scene in the
1038
+ * // azimuth only
1039
+ *
1040
+ * figure.add([
1041
+ * {
1042
+ * make: 'cylinder',
1043
+ * radius: 0.01,
1044
+ * color: [1, 0, 0, 1],
1045
+ * line: [[-1, 0, 0], [1, 0, 0]],
1046
+ * },
1047
+ * {
1048
+ * make: 'cylinder',
1049
+ * radius: 0.01,
1050
+ * color: [0, 1, 0, 1],
1051
+ * line: [[0, -1, 0], [0, 1, 0]],
1052
+ * },
1053
+ * {
1054
+ * make: 'cylinder',
1055
+ * radius: 0.01,
1056
+ * color: [0, 0, 1, 1],
1057
+ * line: [[0, 0, -1], [0, 0, 1]],
1058
+ * },
1059
+ * {
1060
+ * make: 'grid',
1061
+ * bounds: [-0.8, -0.8, 1.6, 1.6],
1062
+ * xStep: 0.05,
1063
+ * yStep: 0.05,
1064
+ * line: { width: 0.002 },
1065
+ * color: [0.7, 0.7, 0.7, 1],
1066
+ * transform: ['r', Math.PI / 2, 1, 0, 0],
1067
+ * },
1068
+ * ]);
1069
+ *
1070
+ * // Add a moveable cube
1071
+ * figure.add({
1072
+ * make: 'cube',
1073
+ * side: 0.3,
1074
+ * color: [1, 0, 0, 1],
1075
+ * center: [0.3, 0, 0],
1076
+ * move: {
1077
+ * plane: [[0, 0, 0], [0, 1, 0]],
1078
+ * },
1079
+ * });
1080
+ *
1081
+ * // Add camera control bar at the bottom of the screen that only allows
1082
+ * // rotation in the azimuth. As the camera control bar does not overlap the
1083
+ * // cube, then both the cube can moved, and the scene rotated with the bar.
1084
+ * figure.add({
1085
+ * make: 'cameraControl',
1086
+ * color: [0, 0, 0, 0.2],
1087
+ * ySensitivity: 0,
1088
+ * height: 0.1,
1089
+ * });
1090
+
1091
+ * @interface
1092
+ * @group Interactivity
1093
+ */
1094
+ export type OBJ_CameraControl = {
1095
+ left?: number;
1096
+ bottom?: number;
1097
+ width?: number;
1098
+ height?: number;
1099
+ axis?: TypeParsablePoint;
1100
+ controlScene?: Scene | string;
1101
+ sensitivity?: number;
1102
+ xSensitivity?: number;
1103
+ ySensitivity?: number;
1104
+ back?: boolean;
1105
+ } & OBJ_FigurePrimitive;