ballistics-engine 0.13.3

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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Alex Jokela
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,614 @@
1
+ # Ballistics Engine
2
+
3
+ A high-performance ballistics trajectory calculation engine with comprehensive physics modeling, automatic zeroing, and statistical analysis capabilities.
4
+
5
+ **Project Website:** [https://ballistics.rs/](https://ballistics.rs/)
6
+
7
+ ## Features
8
+
9
+ - **Full 3D Trajectory Integration** - Six-state ballistic modeling with adaptive RK45 and fixed-step RK4 integration methods
10
+ - **Advanced Drag Models** - Support for G1, G7, and custom drag curves with automatic transonic corrections
11
+ - **Automatic Zeroing** - Calculate sight adjustments and apply zero angles automatically
12
+ - **Unit Conversion** - Seamless switching between Imperial (default) and Metric units
13
+ - **BC Segmentation** - Velocity-dependent ballistic coefficient modeling with automatic estimation
14
+ - **Atmospheric Modeling** - Temperature, pressure, humidity, and altitude effects with ICAO standard atmosphere
15
+ - **Wind Effects** - 3D wind calculations with altitude-dependent wind shear modeling
16
+ - **Monte Carlo Simulations** - Statistical analysis with parameter uncertainties
17
+ - **BC Estimation** - Estimate ballistic coefficients from trajectory data
18
+ - **Advanced Physics**:
19
+ - **Spin Effects**: Magnus effect, enhanced spin drift with decay modeling
20
+ - **Earth Effects**: Coriolis effect with latitude-dependent calculations
21
+ - **Angular Motion**: Gyroscopic precession and nutation physics
22
+ - **Transonic Analysis**: Pitch damping coefficients and stability warnings
23
+ - **Trajectory Sampling**: Regular interval data collection for analysis
24
+ - **Form Factor Corrections**: Bullet-specific drag adjustments
25
+ - **Multiple Output Formats** - JSON, CSV, and formatted tables
26
+
27
+ ## Installation
28
+
29
+ ### From Source
30
+
31
+ ```bash
32
+ git clone https://github.com/ajokela/ballistics-engine.git
33
+ cd ballistics-engine
34
+ cargo build --release
35
+ ```
36
+
37
+ The binary will be at: `target/release/ballistics`
38
+
39
+ ## Quick Start
40
+
41
+ ### Basic Trajectory (Imperial Units - Default)
42
+
43
+ ```bash
44
+ # .308 Winchester, 168gr bullet at 2700 fps
45
+ ./ballistics trajectory -v 2700 -b 0.475 -m 168 -d 0.308 --max-range 1000
46
+
47
+ # With automatic zeroing at 200 yards
48
+ ./ballistics trajectory -v 2700 -b 0.475 -m 168 -d 0.308 --auto-zero 200 --max-range 500
49
+ ```
50
+
51
+ ### Metric Units
52
+
53
+ ```bash
54
+ # Same bullet in metric units
55
+ ./ballistics trajectory --units metric -v 823 -b 0.475 -m 10.9 -d 7.82 --max-range 1000
56
+ ```
57
+
58
+ ## Unit Systems
59
+
60
+ The engine supports two unit systems, selectable with the `--units` flag:
61
+
62
+ ### Imperial (Default)
63
+ - **Velocity**: feet per second (fps)
64
+ - **Mass**: grains
65
+ - **Distance**: yards
66
+ - **Diameter**: inches
67
+ - **Temperature**: Fahrenheit
68
+ - **Pressure**: inHg
69
+ - **Wind**: mph
70
+
71
+ ### Metric
72
+ - **Velocity**: meters per second (m/s)
73
+ - **Mass**: grams
74
+ - **Distance**: meters
75
+ - **Diameter**: millimeters
76
+ - **Temperature**: Celsius
77
+ - **Pressure**: hPa (millibars)
78
+ - **Wind**: m/s
79
+
80
+ ## Commands
81
+
82
+ ### Trajectory Calculation
83
+
84
+ Calculate ballistic trajectory with environmental conditions:
85
+
86
+ ```bash
87
+ # Imperial units (default)
88
+ ./ballistics trajectory \
89
+ -v 2700 # Velocity (fps)
90
+ -b 0.475 # Ballistic coefficient
91
+ -m 168 # Mass (grains)
92
+ -d 0.308 # Diameter (inches)
93
+ --drag-model g7 # G7 drag model
94
+ --angle 0 # Launch angle (degrees)
95
+ --max-range 1000 # Maximum range (yards)
96
+ --wind-speed 10 # Wind speed (mph)
97
+ --wind-direction 90 # Wind from right (degrees)
98
+ --temperature 59 # Temperature (Fahrenheit)
99
+ --pressure 29.92 # Pressure (inHg)
100
+ --humidity 50 # Relative humidity (%)
101
+ --altitude 0 # Altitude (feet)
102
+ --full # Show all trajectory points
103
+ ```
104
+
105
+ #### Auto-Zero Feature
106
+
107
+ Automatically calculate and apply the zero angle for a specific distance:
108
+
109
+ ```bash
110
+ # Zero at 200 yards and show trajectory to 500 yards
111
+ ./ballistics trajectory \
112
+ -v 2700 -b 0.475 -m 168 -d 0.308 \
113
+ --auto-zero 200 \ # Automatically zero at 200 yards
114
+ --max-range 500 \
115
+ --full
116
+
117
+ # Custom sight height for auto-zero
118
+ ./ballistics trajectory \
119
+ -v 2700 -b 0.475 -m 168 -d 0.308 \
120
+ --auto-zero 100 \
121
+ --sight-height 0.055 # 2.2 inches in yards
122
+ ```
123
+
124
+ #### Advanced BC Modeling
125
+
126
+ Enable velocity-dependent BC modeling for more accurate long-range predictions:
127
+
128
+ ```bash
129
+ # Enable BC segmentation (velocity-based BC changes)
130
+ ./ballistics trajectory \
131
+ -v 2700 -b 0.475 -m 168 -d 0.308 \
132
+ --use-bc-segments \
133
+ --auto-zero 600 \
134
+ --max-range 1000
135
+ ```
136
+
137
+ #### Advanced Physics - Magnus and Spin Drift
138
+
139
+ Enable advanced gyroscopic and aerodynamic effects:
140
+
141
+ ```bash
142
+ # Magnus effect and spin drift calculation
143
+ ./ballistics trajectory \
144
+ -v 2700 -b 0.475 -m 168 -d 0.308 \
145
+ --twist-rate 10 # 1:10" barrel twist
146
+ --twist-right # Right-hand twist
147
+ --enable-magnus # Enable Magnus effect
148
+ --enable-spin-drift # Enable enhanced spin drift
149
+ --wind-speed 10 \
150
+ --wind-direction 90 \
151
+ --max-range 1000
152
+
153
+ # Coriolis effect for extreme long range
154
+ ./ballistics trajectory \
155
+ -v 3000 -b 0.750 -m 250 -d 0.338 \
156
+ --enable-coriolis \
157
+ --latitude 45 # Shooting latitude
158
+ --shooting-angle 90 # Azimuth (0=N, 90=E)
159
+ --max-range 2000
160
+ ```
161
+
162
+ ### Zero Calculation
163
+
164
+ Calculate the sight adjustment needed to zero at a specific distance:
165
+
166
+ ```bash
167
+ # Calculate zero for 200 yards
168
+ ./ballistics zero \
169
+ -v 2700 -b 0.475 -m 168 -d 0.308 \
170
+ --target-distance 200
171
+
172
+ # With custom sight height (default is 0.05 yards / 1.8 inches)
173
+ ./ballistics zero \
174
+ -v 2700 -b 0.475 -m 168 -d 0.308 \
175
+ --target-distance 300 \
176
+ --sight-height 0.055 # 2.2 inches
177
+
178
+ # Metric example
179
+ ./ballistics zero --units metric \
180
+ -v 823 -b 0.475 -m 10.9 -d 7.82 \
181
+ --target-distance 200 # 200 meters
182
+ ```
183
+
184
+ Output includes:
185
+ - Zero angle in degrees
186
+ - Adjustment in MOA (Minutes of Angle)
187
+ - Adjustment in mrad (milliradians)
188
+ - Maximum ordinate (highest point of trajectory)
189
+
190
+ ### Monte Carlo Simulation
191
+
192
+ Run statistical analysis with parameter variations:
193
+
194
+ ```bash
195
+ ./ballistics monte-carlo \
196
+ -v 2700 # Base velocity (fps)
197
+ -b 0.475 # Base BC
198
+ -m 168 # Mass (grains)
199
+ -d 0.308 # Diameter (inches)
200
+ -n 1000 # Number of simulations
201
+ --velocity-std 10 # Velocity std dev (fps)
202
+ --angle-std 0.5 # Angle std dev (degrees)
203
+ --bc-std 0.01 # BC std dev
204
+ --wind-std 2 # Wind speed std dev (mph)
205
+ --target-distance 300 # Target distance for hit probability
206
+ ```
207
+
208
+ ### BC Estimation
209
+
210
+ Estimate ballistic coefficient from observed trajectory data:
211
+
212
+ ```bash
213
+ ./ballistics estimate-bc \
214
+ -v 2700 -m 168 -d 0.308 \
215
+ --distance1 100 --drop1 0.0 # First data point
216
+ --distance2 200 --drop2 0.023 # Second data point
217
+ ```
218
+
219
+ ## Advanced Features
220
+
221
+ ### Integration Methods
222
+
223
+ The engine supports two numerical integration methods:
224
+
225
+ - **RK45 (Dormand-Prince Adaptive)** - Default method, provides best accuracy with adaptive step sizing
226
+ - **RK4 (Runge-Kutta 4th Order Fixed-Step)** - Available with `--use-rk4-fixed` flag for faster computation
227
+
228
+ ### Wind Shear Modeling
229
+
230
+ Model altitude-dependent wind variations:
231
+
232
+ ```bash
233
+ ./ballistics trajectory -v 2700 -b 0.475 -m 168 -d 0.308 \
234
+ --wind-speed 10 --wind-direction 90 \
235
+ --enable-wind-shear \
236
+ --max-range 1000
237
+ ```
238
+
239
+ ### Transonic Stability Analysis
240
+
241
+ Analyze projectile stability through the transonic regime:
242
+
243
+ ```bash
244
+ ./ballistics trajectory -v 3000 -b 0.475 -m 168 -d 0.308 \
245
+ --enable-pitch-damping \
246
+ --max-range 2000
247
+ ```
248
+
249
+ Provides warnings about transonic instability and minimum pitch damping coefficients.
250
+
251
+ ### Trajectory Sampling
252
+
253
+ Collect trajectory data at regular intervals for detailed analysis:
254
+
255
+ ```bash
256
+ ./ballistics trajectory -v 2700 -b 0.475 -m 168 -d 0.308 \
257
+ --sample-trajectory \
258
+ --sample-interval 25 # Sample every 25 yards
259
+ --max-range 1000 -o json
260
+ ```
261
+
262
+ ### Angular Motion Physics
263
+
264
+ Model precession and nutation of spinning projectiles:
265
+
266
+ ```bash
267
+ ./ballistics trajectory -v 2700 -b 0.475 -m 168 -d 0.308 \
268
+ --twist-rate 10 \
269
+ --enable-precession \
270
+ --max-range 1000
271
+ ```
272
+
273
+ ### Complete Advanced Physics Example
274
+
275
+ ```bash
276
+ ./ballistics trajectory \
277
+ -v 2850 -b 0.690 -m 230 -d 0.338 \
278
+ --drag-model g7 \
279
+ --twist-rate 8.5 --twist-right \
280
+ --enable-magnus \
281
+ --enable-coriolis \
282
+ --enable-spin-drift \
283
+ --enable-wind-shear \
284
+ --enable-pitch-damping \
285
+ --enable-precession \
286
+ --sample-trajectory \
287
+ --latitude 38.5 \
288
+ --shooting-angle 45 \
289
+ --wind-speed 15 --wind-direction 270 \
290
+ --altitude 6000 \
291
+ --max-range 2000
292
+ ```
293
+
294
+ ## Physics Modeling
295
+
296
+ The ballistics engine implements comprehensive physics modeling for accurate trajectory prediction:
297
+
298
+ ### Aerodynamic Effects
299
+ - **Drag Modeling** - Multiple drag functions (G1-G8, JBM, custom curves) with transonic flow corrections
300
+ - **Form Factor** - Projectile efficiency corrections based on shape and design
301
+ - **Reynolds Number Effects** - Viscosity and flow regime corrections
302
+
303
+ ### Gyroscopic Effects
304
+ - **Spin Drift** - Lateral deviation due to gyroscopic and Magnus effects
305
+ - **Precession** - Gyroscopic precession of spinning projectile
306
+ - **Nutation** - Oscillatory motion superimposed on precession
307
+ - **Spin Decay** - Reduction in spin rate over time due to aerodynamic damping
308
+ - **Pitch Damping** - Aerodynamic moments opposing angular motion
309
+
310
+ ### Environmental Effects
311
+ - **Coriolis Effect** - Earth's rotation influence on long-range trajectories
312
+ - **Magnus Effect** - Force from spinning projectile in crossflow
313
+ - **Wind Shear** - Altitude-dependent wind variations
314
+ - **Atmospheric Stratification** - Density and sound speed variations with altitude
315
+
316
+ ### Stability Modeling
317
+ - **Dynamic Stability** - Gyroscopic and aerodynamic stability calculations
318
+ - **Yaw of Repose** - Equilibrium yaw angle in crosswind
319
+ - **Limit Cycle Yaw** - Bounded oscillatory motion analysis
320
+
321
+ ## FFI Layer
322
+
323
+ The library includes a Foreign Function Interface (FFI) layer for integration with iOS, Android, and other platforms. The FFI provides C-compatible bindings for all major functionality.
324
+
325
+ <img src="ios.png" alt="iOS Integration Example" width="35%">
326
+
327
+ ### FFI Features
328
+ - **C-Compatible Structures** - All data structures use C-compatible layouts
329
+ - **Safe Memory Management** - Proper handling of memory across language boundaries
330
+ - **iOS/Swift Integration** - Ready for use with Swift through bridging headers
331
+ - **Android/JNI Support** - Compatible with Java Native Interface
332
+ - **Monte Carlo Simulation** - Statistical analysis with parameter variations
333
+ - **Error Handling** - Graceful error propagation across FFI boundary
334
+
335
+ ### Example FFI Usage (C/Swift)
336
+ ```c
337
+ // Create input parameters
338
+ FFIBallisticInputs inputs = {
339
+ .muzzle_velocity = 823.0, // m/s
340
+ .ballistic_coefficient = 0.475,
341
+ .mass = 0.0109, // kg
342
+ .diameter = 0.00782, // meters
343
+ .drag_model = 0, // G1
344
+ .sight_height = 0.05, // meters
345
+ .temperature = 15.0, // Celsius
346
+ .altitude = 0.0
347
+ };
348
+
349
+ // Calculate trajectory
350
+ FFITrajectoryResult* result = ballistics_calculate_trajectory(&inputs, NULL, NULL, 1000.0, 0.1);
351
+
352
+ // Use results
353
+ printf("Max range: %.2f meters\n", result->max_range);
354
+
355
+ // Clean up
356
+ ballistics_free_trajectory_result(result);
357
+ ```
358
+
359
+ ### Monte Carlo Simulation via FFI
360
+ ```c
361
+ // Set up Monte Carlo parameters
362
+ FFIMonteCarloParams params = {
363
+ .num_simulations = 1000,
364
+ .velocity_std_dev = 10.0, // m/s variation
365
+ .angle_std_dev = 0.001, // radian variation (elevation)
366
+ .bc_std_dev = 0.01, // BC variation
367
+ .wind_speed_std_dev = 2.0, // m/s wind variation
368
+ .target_distance = 600.0, // Target at 600m
369
+ .azimuth_std_dev = 0.001 // radian variation (horizontal)
370
+ };
371
+
372
+ // Run simulation
373
+ FFIMonteCarloResults* results = ballistics_monte_carlo(&inputs, NULL, &params);
374
+
375
+ // Use statistical results
376
+ printf("Mean range: %.2f m (σ=%.2f)\n", results->mean_range, results->std_dev_range);
377
+ printf("Hit probability at 600m: %.1f%%\n", results->hit_probability * 100);
378
+
379
+ // Access individual shots
380
+ for (int i = 0; i < results->num_results; i++) {
381
+ printf("Shot %d: Range %.2f m, Impact velocity %.2f m/s\n",
382
+ i, results->ranges[i], results->impact_velocities[i]);
383
+ }
384
+
385
+ // Clean up
386
+ ballistics_free_monte_carlo_results(results);
387
+ ```
388
+
389
+ ## Output Formats
390
+
391
+ All commands support three output formats via the `-o` flag:
392
+
393
+ - **table** (default) - Formatted ASCII table for terminal display
394
+ - **json** - Complete data in JSON format for programmatic use
395
+ - **csv** - Comma-separated values for spreadsheet analysis
396
+
397
+ ## Practical Examples
398
+
399
+ ### Hunting Zero
400
+
401
+ Zero a hunting rifle at 200 yards with environmental conditions:
402
+
403
+ ```bash
404
+ # Calculate zero angle
405
+ ./ballistics zero \
406
+ -v 2650 -b 0.460 -m 180 -d 0.308 \
407
+ --target-distance 200
408
+
409
+ # Verify trajectory with auto-zero
410
+ ./ballistics trajectory \
411
+ -v 2650 -b 0.460 -m 180 -d 0.308 \
412
+ --auto-zero 200 \
413
+ --max-range 400 \
414
+ --wind-speed 15 \
415
+ --wind-direction 270 \
416
+ --temperature 32 \
417
+ --humidity 30 \
418
+ --altitude 5000 \
419
+ --full
420
+ ```
421
+
422
+ ### Long Range Shooting
423
+
424
+ Analyze trajectory for 1000-yard shot:
425
+
426
+ ```bash
427
+ ./ballistics trajectory \
428
+ -v 2850 -b 0.690 -m 230 -d 0.338 \
429
+ --drag-model g7 \
430
+ --auto-zero 100 \
431
+ --max-range 1100 \
432
+ --wind-speed 10 \
433
+ --wind-direction 45 \
434
+ --full \
435
+ -o json > trajectory.json
436
+ ```
437
+
438
+ ### Load Development
439
+
440
+ Compare different loads using Monte Carlo:
441
+
442
+ ```bash
443
+ # Load 1: Higher velocity, more variation
444
+ ./ballistics monte-carlo \
445
+ -v 2750 -b 0.475 -m 168 -d 0.308 \
446
+ -n 1000 \
447
+ --velocity-std 15 \
448
+ --target-distance 600
449
+
450
+ # Load 2: Lower velocity, more consistent
451
+ ./ballistics monte-carlo \
452
+ -v 2680 -b 0.475 -m 168 -d 0.308 \
453
+ -n 1000 \
454
+ --velocity-std 8 \
455
+ --target-distance 600
456
+ ```
457
+
458
+ ## Advanced Features
459
+
460
+ ### BC Segmentation
461
+
462
+ Velocity-dependent BC modeling accounts for how ballistic coefficient changes as the bullet slows down. Enable with `--use-bc-segments`:
463
+
464
+ - Automatically estimates BC segments based on bullet characteristics
465
+ - No external data required - uses caliber, weight, and BC
466
+ - Identifies bullet type (Match, Hunting, VLD, etc.) from parameters
467
+ - Applies physics-based BC degradation curves
468
+
469
+ Example:
470
+ ```bash
471
+ ./ballistics trajectory -v 2700 -b 0.475 -m 168 -d 0.308 --use-bc-segments --max-range 1000
472
+ ```
473
+
474
+
475
+ ### Advanced Physics Modeling
476
+
477
+ When enabled, the engine calculates:
478
+ - **Magnus Effect** - Side force from spinning projectiles
479
+ - **Spin Drift** - Lateral drift due to gyroscopic effects
480
+ - **Coriolis Effect** - Earth rotation effects (with latitude input)
481
+ - **Transonic Drag** - Enhanced drag modeling in transonic regime
482
+ - **Reynolds Number Corrections** - Viscous effects at low velocities
483
+
484
+ ## Building from Source
485
+
486
+ ### Requirements
487
+
488
+ - Rust 1.70 or later
489
+ - Cargo build system
490
+
491
+ ### Build Commands
492
+
493
+ ```bash
494
+ # Debug build
495
+ cargo build
496
+
497
+ # Release build (optimized)
498
+ cargo build --release
499
+
500
+ # Run tests
501
+ cargo test
502
+
503
+ # Build documentation
504
+ cargo doc --open
505
+ ```
506
+
507
+ ## Library Usage
508
+
509
+ Use as a Rust library in your own projects:
510
+
511
+ ```rust
512
+ use ballistics_engine::{
513
+ BallisticInputs, TrajectorySolver,
514
+ WindConditions, AtmosphericConditions
515
+ };
516
+
517
+ fn main() -> Result<(), Box<dyn std::error::Error>> {
518
+ let inputs = BallisticInputs {
519
+ muzzle_velocity: 823.0, // m/s
520
+ launch_angle: 0.0, // radians
521
+ ballistic_coefficient: 0.475,
522
+ mass: 0.0109, // kg
523
+ diameter: 0.00782, // meters
524
+ sight_height: 0.05, // meters
525
+ ..Default::default()
526
+ };
527
+
528
+ let wind = WindConditions {
529
+ speed: 5.0, // m/s
530
+ direction: 1.5708, // 90 degrees in radians
531
+ ..Default::default()
532
+ };
533
+
534
+ let atmosphere = AtmosphericConditions {
535
+ temperature: 15.0, // Celsius
536
+ pressure: 1013.25, // hPa
537
+ humidity: 50.0, // %
538
+ altitude: 0.0, // meters
539
+ ..Default::default()
540
+ };
541
+
542
+ let solver = TrajectorySolver::new(inputs, wind, atmosphere);
543
+ let result = solver.solve()?;
544
+
545
+ println!("Max range: {:.2} m", result.max_range);
546
+ println!("Max height: {:.2} m", result.max_height);
547
+ println!("Time of flight: {:.3} s", result.time_of_flight);
548
+
549
+ Ok(())
550
+ }
551
+ ```
552
+
553
+ ## Performance
554
+
555
+ Optimized Rust implementation provides:
556
+ - Single trajectory (1000m): ~5ms
557
+ - Monte Carlo (1000 runs): ~500ms
558
+ - BC estimation: ~50ms
559
+ - Zero calculation: ~10ms
560
+
561
+ ## Common Ballistic Coefficients
562
+
563
+ | Caliber | Weight | BC (G1) | BC (G7) | Description |
564
+ |---------|--------|---------|---------|-------------|
565
+ | .223 | 55gr | 0.250 | - | FMJ |
566
+ | .223 | 77gr | 0.362 | 0.182 | Match |
567
+ | .308 | 168gr | 0.475 | 0.224 | Match |
568
+ | .308 | 175gr | 0.505 | 0.253 | Match |
569
+ | .308 | 180gr | 0.480 | - | Hunting |
570
+ | .338 | 300gr | 0.768 | 0.383 | Match |
571
+ | 6.5mm | 140gr | 0.620 | 0.310 | Match |
572
+ | .50 | 750gr | 1.050 | 0.520 | Match |
573
+
574
+ ## Troubleshooting
575
+
576
+ ### Trajectory hits ground early
577
+ - Check if you're using `--auto-zero` or setting `--angle` manually
578
+ - Default angle is 0° (horizontal), which will hit ground quickly
579
+ - Use `--auto-zero <distance>` to automatically calculate proper angle
580
+
581
+ ### Units confusion
582
+ - Default is Imperial (fps, grains, yards)
583
+ - Use `--units metric` for metric system
584
+ - All inputs must match the selected unit system
585
+
586
+ ### Unexpected BC behavior
587
+ - G1 and G7 models have different BC values for same bullet
588
+ - G7 typically better for boat-tail bullets
589
+ - BC segmentation automatically applied based on bullet type
590
+
591
+ ## Contributing
592
+
593
+ Contributions are welcome! Please:
594
+ 1. Fork the repository
595
+ 2. Create a feature branch
596
+ 3. Add tests for new features
597
+ 4. Run `cargo test` and `cargo fmt`
598
+ 5. Submit a pull request
599
+
600
+ ## License
601
+
602
+ This project is licensed under the MIT License - see LICENSE file for details.
603
+
604
+ ## Acknowledgments
605
+
606
+ - Ballistics physics based on Robert McCoy's "Modern Exterior Ballistics"
607
+ - Drag tables from military ballistics research
608
+ - BC segmentation algorithms from Bryan Litz's research
609
+ - Community contributions and testing
610
+
611
+ ## Support
612
+
613
+ For issues, questions, or contributions:
614
+ - GitHub Issues: [github.com/ajokela/ballistics-engine/issues](https://github.com/ajokela/ballistics-engine/issues)
@@ -0,0 +1,49 @@
1
+ /* tslint:disable */
2
+ /* eslint-disable */
3
+ /**
4
+ * Object-oriented calculator for programmatic use
5
+ * Provides a type-safe, fluent API alternative to the CLI interface
6
+ */
7
+ export class Calculator {
8
+ free(): void;
9
+ [Symbol.dispose](): void;
10
+ setAltitude(altitude_ft: number): Calculator;
11
+ setDiameter(diameter_inches: number): Calculator;
12
+ setHumidity(humidity: number): Calculator;
13
+ setPressure(pressure_inhg: number): Calculator;
14
+ setVelocity(velocity_fps: number): Calculator;
15
+ setMaxRange(range_yards: number): Calculator;
16
+ setDragModel(model: string): Calculator;
17
+ setZeroRange(range_yards: number): Calculator;
18
+ setTemperature(temp_f: number): Calculator;
19
+ setSightHeight(height_inches: number): Calculator;
20
+ enableCoriolis(enabled: boolean, latitude?: number | null): Calculator;
21
+ /**
22
+ * Get full trajectory table as array of points
23
+ * Returns array of: [{ range_yards, drop_inches, windage_inches, velocity_fps, energy_ftlb, time_sec }, ...]
24
+ */
25
+ getFullTrajectory(): any;
26
+ /**
27
+ * Calculate trajectory and return result as JavaScript object
28
+ * Returns: { range_yards, drop_inches, windage_inches, velocity_fps, energy_ftlb, time_sec }
29
+ */
30
+ calculateTrajectory(range_yards: number): any;
31
+ enableSpinDrift(enabled: boolean, twist_rate?: number | null): Calculator;
32
+ /**
33
+ * Create a new calculator with default values
34
+ * Defaults: .308 Winchester 168gr at 2700 fps, standard atmosphere
35
+ */
36
+ constructor();
37
+ setBC(bc: number): Calculator;
38
+ setMass(mass_grains: number): Calculator;
39
+ setWind(speed_mph: number, direction_deg: number): Calculator;
40
+ }
41
+ export class WasmBallistics {
42
+ free(): void;
43
+ [Symbol.dispose](): void;
44
+ /**
45
+ * Run a command and return the output
46
+ */
47
+ runCommand(command: string): string;
48
+ constructor();
49
+ }
@@ -0,0 +1,544 @@
1
+
2
+ let imports = {};
3
+ imports['__wbindgen_placeholder__'] = module.exports;
4
+
5
+ let cachedUint8ArrayMemory0 = null;
6
+
7
+ function getUint8ArrayMemory0() {
8
+ if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) {
9
+ cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer);
10
+ }
11
+ return cachedUint8ArrayMemory0;
12
+ }
13
+
14
+ let cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
15
+
16
+ cachedTextDecoder.decode();
17
+
18
+ function decodeText(ptr, len) {
19
+ return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len));
20
+ }
21
+
22
+ function getStringFromWasm0(ptr, len) {
23
+ ptr = ptr >>> 0;
24
+ return decodeText(ptr, len);
25
+ }
26
+
27
+ function addToExternrefTable0(obj) {
28
+ const idx = wasm.__externref_table_alloc();
29
+ wasm.__wbindgen_externrefs.set(idx, obj);
30
+ return idx;
31
+ }
32
+
33
+ function handleError(f, args) {
34
+ try {
35
+ return f.apply(this, args);
36
+ } catch (e) {
37
+ const idx = addToExternrefTable0(e);
38
+ wasm.__wbindgen_exn_store(idx);
39
+ }
40
+ }
41
+
42
+ function getArrayU8FromWasm0(ptr, len) {
43
+ ptr = ptr >>> 0;
44
+ return getUint8ArrayMemory0().subarray(ptr / 1, ptr / 1 + len);
45
+ }
46
+
47
+ function isLikeNone(x) {
48
+ return x === undefined || x === null;
49
+ }
50
+
51
+ let WASM_VECTOR_LEN = 0;
52
+
53
+ const cachedTextEncoder = new TextEncoder();
54
+
55
+ if (!('encodeInto' in cachedTextEncoder)) {
56
+ cachedTextEncoder.encodeInto = function (arg, view) {
57
+ const buf = cachedTextEncoder.encode(arg);
58
+ view.set(buf);
59
+ return {
60
+ read: arg.length,
61
+ written: buf.length
62
+ };
63
+ }
64
+ }
65
+
66
+ function passStringToWasm0(arg, malloc, realloc) {
67
+
68
+ if (realloc === undefined) {
69
+ const buf = cachedTextEncoder.encode(arg);
70
+ const ptr = malloc(buf.length, 1) >>> 0;
71
+ getUint8ArrayMemory0().subarray(ptr, ptr + buf.length).set(buf);
72
+ WASM_VECTOR_LEN = buf.length;
73
+ return ptr;
74
+ }
75
+
76
+ let len = arg.length;
77
+ let ptr = malloc(len, 1) >>> 0;
78
+
79
+ const mem = getUint8ArrayMemory0();
80
+
81
+ let offset = 0;
82
+
83
+ for (; offset < len; offset++) {
84
+ const code = arg.charCodeAt(offset);
85
+ if (code > 0x7F) break;
86
+ mem[ptr + offset] = code;
87
+ }
88
+
89
+ if (offset !== len) {
90
+ if (offset !== 0) {
91
+ arg = arg.slice(offset);
92
+ }
93
+ ptr = realloc(ptr, len, len = offset + arg.length * 3, 1) >>> 0;
94
+ const view = getUint8ArrayMemory0().subarray(ptr + offset, ptr + len);
95
+ const ret = cachedTextEncoder.encodeInto(arg, view);
96
+
97
+ offset += ret.written;
98
+ ptr = realloc(ptr, len, offset, 1) >>> 0;
99
+ }
100
+
101
+ WASM_VECTOR_LEN = offset;
102
+ return ptr;
103
+ }
104
+
105
+ function takeFromExternrefTable0(idx) {
106
+ const value = wasm.__wbindgen_externrefs.get(idx);
107
+ wasm.__externref_table_dealloc(idx);
108
+ return value;
109
+ }
110
+
111
+ const CalculatorFinalization = (typeof FinalizationRegistry === 'undefined')
112
+ ? { register: () => {}, unregister: () => {} }
113
+ : new FinalizationRegistry(ptr => wasm.__wbg_calculator_free(ptr >>> 0, 1));
114
+ /**
115
+ * Object-oriented calculator for programmatic use
116
+ * Provides a type-safe, fluent API alternative to the CLI interface
117
+ */
118
+ class Calculator {
119
+
120
+ static __wrap(ptr) {
121
+ ptr = ptr >>> 0;
122
+ const obj = Object.create(Calculator.prototype);
123
+ obj.__wbg_ptr = ptr;
124
+ CalculatorFinalization.register(obj, obj.__wbg_ptr, obj);
125
+ return obj;
126
+ }
127
+
128
+ __destroy_into_raw() {
129
+ const ptr = this.__wbg_ptr;
130
+ this.__wbg_ptr = 0;
131
+ CalculatorFinalization.unregister(this);
132
+ return ptr;
133
+ }
134
+
135
+ free() {
136
+ const ptr = this.__destroy_into_raw();
137
+ wasm.__wbg_calculator_free(ptr, 0);
138
+ }
139
+ /**
140
+ * @param {number} altitude_ft
141
+ * @returns {Calculator}
142
+ */
143
+ setAltitude(altitude_ft) {
144
+ const ptr = this.__destroy_into_raw();
145
+ const ret = wasm.calculator_setAltitude(ptr, altitude_ft);
146
+ return Calculator.__wrap(ret);
147
+ }
148
+ /**
149
+ * @param {number} diameter_inches
150
+ * @returns {Calculator}
151
+ */
152
+ setDiameter(diameter_inches) {
153
+ const ptr = this.__destroy_into_raw();
154
+ const ret = wasm.calculator_setDiameter(ptr, diameter_inches);
155
+ return Calculator.__wrap(ret);
156
+ }
157
+ /**
158
+ * @param {number} humidity
159
+ * @returns {Calculator}
160
+ */
161
+ setHumidity(humidity) {
162
+ const ptr = this.__destroy_into_raw();
163
+ const ret = wasm.calculator_setHumidity(ptr, humidity);
164
+ return Calculator.__wrap(ret);
165
+ }
166
+ /**
167
+ * @param {number} pressure_inhg
168
+ * @returns {Calculator}
169
+ */
170
+ setPressure(pressure_inhg) {
171
+ const ptr = this.__destroy_into_raw();
172
+ const ret = wasm.calculator_setPressure(ptr, pressure_inhg);
173
+ return Calculator.__wrap(ret);
174
+ }
175
+ /**
176
+ * @param {number} velocity_fps
177
+ * @returns {Calculator}
178
+ */
179
+ setVelocity(velocity_fps) {
180
+ const ptr = this.__destroy_into_raw();
181
+ const ret = wasm.calculator_setVelocity(ptr, velocity_fps);
182
+ return Calculator.__wrap(ret);
183
+ }
184
+ /**
185
+ * @param {number} range_yards
186
+ * @returns {Calculator}
187
+ */
188
+ setMaxRange(range_yards) {
189
+ const ptr = this.__destroy_into_raw();
190
+ const ret = wasm.calculator_setMaxRange(ptr, range_yards);
191
+ return Calculator.__wrap(ret);
192
+ }
193
+ /**
194
+ * @param {string} model
195
+ * @returns {Calculator}
196
+ */
197
+ setDragModel(model) {
198
+ const ptr = this.__destroy_into_raw();
199
+ const ptr0 = passStringToWasm0(model, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
200
+ const len0 = WASM_VECTOR_LEN;
201
+ const ret = wasm.calculator_setDragModel(ptr, ptr0, len0);
202
+ return Calculator.__wrap(ret);
203
+ }
204
+ /**
205
+ * @param {number} range_yards
206
+ * @returns {Calculator}
207
+ */
208
+ setZeroRange(range_yards) {
209
+ const ptr = this.__destroy_into_raw();
210
+ const ret = wasm.calculator_setZeroRange(ptr, range_yards);
211
+ return Calculator.__wrap(ret);
212
+ }
213
+ /**
214
+ * @param {number} temp_f
215
+ * @returns {Calculator}
216
+ */
217
+ setTemperature(temp_f) {
218
+ const ptr = this.__destroy_into_raw();
219
+ const ret = wasm.calculator_setTemperature(ptr, temp_f);
220
+ return Calculator.__wrap(ret);
221
+ }
222
+ /**
223
+ * @param {number} height_inches
224
+ * @returns {Calculator}
225
+ */
226
+ setSightHeight(height_inches) {
227
+ const ptr = this.__destroy_into_raw();
228
+ const ret = wasm.calculator_setSightHeight(ptr, height_inches);
229
+ return Calculator.__wrap(ret);
230
+ }
231
+ /**
232
+ * @param {boolean} enabled
233
+ * @param {number | null} [latitude]
234
+ * @returns {Calculator}
235
+ */
236
+ enableCoriolis(enabled, latitude) {
237
+ const ptr = this.__destroy_into_raw();
238
+ const ret = wasm.calculator_enableCoriolis(ptr, enabled, !isLikeNone(latitude), isLikeNone(latitude) ? 0 : latitude);
239
+ return Calculator.__wrap(ret);
240
+ }
241
+ /**
242
+ * Get full trajectory table as array of points
243
+ * Returns array of: [{ range_yards, drop_inches, windage_inches, velocity_fps, energy_ftlb, time_sec }, ...]
244
+ * @returns {any}
245
+ */
246
+ getFullTrajectory() {
247
+ const ret = wasm.calculator_getFullTrajectory(this.__wbg_ptr);
248
+ if (ret[2]) {
249
+ throw takeFromExternrefTable0(ret[1]);
250
+ }
251
+ return takeFromExternrefTable0(ret[0]);
252
+ }
253
+ /**
254
+ * Calculate trajectory and return result as JavaScript object
255
+ * Returns: { range_yards, drop_inches, windage_inches, velocity_fps, energy_ftlb, time_sec }
256
+ * @param {number} range_yards
257
+ * @returns {any}
258
+ */
259
+ calculateTrajectory(range_yards) {
260
+ const ret = wasm.calculator_calculateTrajectory(this.__wbg_ptr, range_yards);
261
+ if (ret[2]) {
262
+ throw takeFromExternrefTable0(ret[1]);
263
+ }
264
+ return takeFromExternrefTable0(ret[0]);
265
+ }
266
+ /**
267
+ * @param {boolean} enabled
268
+ * @param {number | null} [twist_rate]
269
+ * @returns {Calculator}
270
+ */
271
+ enableSpinDrift(enabled, twist_rate) {
272
+ const ptr = this.__destroy_into_raw();
273
+ const ret = wasm.calculator_enableSpinDrift(ptr, enabled, !isLikeNone(twist_rate), isLikeNone(twist_rate) ? 0 : twist_rate);
274
+ return Calculator.__wrap(ret);
275
+ }
276
+ /**
277
+ * Create a new calculator with default values
278
+ * Defaults: .308 Winchester 168gr at 2700 fps, standard atmosphere
279
+ */
280
+ constructor() {
281
+ const ret = wasm.calculator_new();
282
+ this.__wbg_ptr = ret >>> 0;
283
+ CalculatorFinalization.register(this, this.__wbg_ptr, this);
284
+ return this;
285
+ }
286
+ /**
287
+ * @param {number} bc
288
+ * @returns {Calculator}
289
+ */
290
+ setBC(bc) {
291
+ const ptr = this.__destroy_into_raw();
292
+ const ret = wasm.calculator_setBC(ptr, bc);
293
+ return Calculator.__wrap(ret);
294
+ }
295
+ /**
296
+ * @param {number} mass_grains
297
+ * @returns {Calculator}
298
+ */
299
+ setMass(mass_grains) {
300
+ const ptr = this.__destroy_into_raw();
301
+ const ret = wasm.calculator_setMass(ptr, mass_grains);
302
+ return Calculator.__wrap(ret);
303
+ }
304
+ /**
305
+ * @param {number} speed_mph
306
+ * @param {number} direction_deg
307
+ * @returns {Calculator}
308
+ */
309
+ setWind(speed_mph, direction_deg) {
310
+ const ptr = this.__destroy_into_raw();
311
+ const ret = wasm.calculator_setWind(ptr, speed_mph, direction_deg);
312
+ return Calculator.__wrap(ret);
313
+ }
314
+ }
315
+ if (Symbol.dispose) Calculator.prototype[Symbol.dispose] = Calculator.prototype.free;
316
+
317
+ exports.Calculator = Calculator;
318
+
319
+ const WasmBallisticsFinalization = (typeof FinalizationRegistry === 'undefined')
320
+ ? { register: () => {}, unregister: () => {} }
321
+ : new FinalizationRegistry(ptr => wasm.__wbg_wasmballistics_free(ptr >>> 0, 1));
322
+
323
+ class WasmBallistics {
324
+
325
+ __destroy_into_raw() {
326
+ const ptr = this.__wbg_ptr;
327
+ this.__wbg_ptr = 0;
328
+ WasmBallisticsFinalization.unregister(this);
329
+ return ptr;
330
+ }
331
+
332
+ free() {
333
+ const ptr = this.__destroy_into_raw();
334
+ wasm.__wbg_wasmballistics_free(ptr, 0);
335
+ }
336
+ /**
337
+ * Run a command and return the output
338
+ * @param {string} command
339
+ * @returns {string}
340
+ */
341
+ runCommand(command) {
342
+ let deferred3_0;
343
+ let deferred3_1;
344
+ try {
345
+ const ptr0 = passStringToWasm0(command, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
346
+ const len0 = WASM_VECTOR_LEN;
347
+ const ret = wasm.wasmballistics_runCommand(this.__wbg_ptr, ptr0, len0);
348
+ var ptr2 = ret[0];
349
+ var len2 = ret[1];
350
+ if (ret[3]) {
351
+ ptr2 = 0; len2 = 0;
352
+ throw takeFromExternrefTable0(ret[2]);
353
+ }
354
+ deferred3_0 = ptr2;
355
+ deferred3_1 = len2;
356
+ return getStringFromWasm0(ptr2, len2);
357
+ } finally {
358
+ wasm.__wbindgen_free(deferred3_0, deferred3_1, 1);
359
+ }
360
+ }
361
+ constructor() {
362
+ const ret = wasm.wasmballistics_new();
363
+ this.__wbg_ptr = ret >>> 0;
364
+ WasmBallisticsFinalization.register(this, this.__wbg_ptr, this);
365
+ return this;
366
+ }
367
+ }
368
+ if (Symbol.dispose) WasmBallistics.prototype[Symbol.dispose] = WasmBallistics.prototype.free;
369
+
370
+ exports.WasmBallistics = WasmBallistics;
371
+
372
+ exports.__wbg___wbindgen_is_function_ee8a6c5833c90377 = function(arg0) {
373
+ const ret = typeof(arg0) === 'function';
374
+ return ret;
375
+ };
376
+
377
+ exports.__wbg___wbindgen_is_object_c818261d21f283a4 = function(arg0) {
378
+ const val = arg0;
379
+ const ret = typeof(val) === 'object' && val !== null;
380
+ return ret;
381
+ };
382
+
383
+ exports.__wbg___wbindgen_is_string_fbb76cb2940daafd = function(arg0) {
384
+ const ret = typeof(arg0) === 'string';
385
+ return ret;
386
+ };
387
+
388
+ exports.__wbg___wbindgen_is_undefined_2d472862bd29a478 = function(arg0) {
389
+ const ret = arg0 === undefined;
390
+ return ret;
391
+ };
392
+
393
+ exports.__wbg___wbindgen_throw_b855445ff6a94295 = function(arg0, arg1) {
394
+ throw new Error(getStringFromWasm0(arg0, arg1));
395
+ };
396
+
397
+ exports.__wbg_call_525440f72fbfc0ea = function() { return handleError(function (arg0, arg1, arg2) {
398
+ const ret = arg0.call(arg1, arg2);
399
+ return ret;
400
+ }, arguments) };
401
+
402
+ exports.__wbg_call_e762c39fa8ea36bf = function() { return handleError(function (arg0, arg1) {
403
+ const ret = arg0.call(arg1);
404
+ return ret;
405
+ }, arguments) };
406
+
407
+ exports.__wbg_crypto_574e78ad8b13b65f = function(arg0) {
408
+ const ret = arg0.crypto;
409
+ return ret;
410
+ };
411
+
412
+ exports.__wbg_getRandomValues_b8f5dbd5f3995a9e = function() { return handleError(function (arg0, arg1) {
413
+ arg0.getRandomValues(arg1);
414
+ }, arguments) };
415
+
416
+ exports.__wbg_length_69bca3cb64fc8748 = function(arg0) {
417
+ const ret = arg0.length;
418
+ return ret;
419
+ };
420
+
421
+ exports.__wbg_msCrypto_a61aeb35a24c1329 = function(arg0) {
422
+ const ret = arg0.msCrypto;
423
+ return ret;
424
+ };
425
+
426
+ exports.__wbg_new_1acc0b6eea89d040 = function() {
427
+ const ret = new Object();
428
+ return ret;
429
+ };
430
+
431
+ exports.__wbg_new_e17d9f43105b08be = function() {
432
+ const ret = new Array();
433
+ return ret;
434
+ };
435
+
436
+ exports.__wbg_new_no_args_ee98eee5275000a4 = function(arg0, arg1) {
437
+ const ret = new Function(getStringFromWasm0(arg0, arg1));
438
+ return ret;
439
+ };
440
+
441
+ exports.__wbg_new_with_length_01aa0dc35aa13543 = function(arg0) {
442
+ const ret = new Uint8Array(arg0 >>> 0);
443
+ return ret;
444
+ };
445
+
446
+ exports.__wbg_node_905d3e251edff8a2 = function(arg0) {
447
+ const ret = arg0.node;
448
+ return ret;
449
+ };
450
+
451
+ exports.__wbg_process_dc0fbacc7c1c06f7 = function(arg0) {
452
+ const ret = arg0.process;
453
+ return ret;
454
+ };
455
+
456
+ exports.__wbg_prototypesetcall_2a6620b6922694b2 = function(arg0, arg1, arg2) {
457
+ Uint8Array.prototype.set.call(getArrayU8FromWasm0(arg0, arg1), arg2);
458
+ };
459
+
460
+ exports.__wbg_push_df81a39d04db858c = function(arg0, arg1) {
461
+ const ret = arg0.push(arg1);
462
+ return ret;
463
+ };
464
+
465
+ exports.__wbg_randomFillSync_ac0988aba3254290 = function() { return handleError(function (arg0, arg1) {
466
+ arg0.randomFillSync(arg1);
467
+ }, arguments) };
468
+
469
+ exports.__wbg_require_60cc747a6bc5215a = function() { return handleError(function () {
470
+ const ret = module.require;
471
+ return ret;
472
+ }, arguments) };
473
+
474
+ exports.__wbg_set_c2abbebe8b9ebee1 = function() { return handleError(function (arg0, arg1, arg2) {
475
+ const ret = Reflect.set(arg0, arg1, arg2);
476
+ return ret;
477
+ }, arguments) };
478
+
479
+ exports.__wbg_static_accessor_GLOBAL_89e1d9ac6a1b250e = function() {
480
+ const ret = typeof global === 'undefined' ? null : global;
481
+ return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
482
+ };
483
+
484
+ exports.__wbg_static_accessor_GLOBAL_THIS_8b530f326a9e48ac = function() {
485
+ const ret = typeof globalThis === 'undefined' ? null : globalThis;
486
+ return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
487
+ };
488
+
489
+ exports.__wbg_static_accessor_SELF_6fdf4b64710cc91b = function() {
490
+ const ret = typeof self === 'undefined' ? null : self;
491
+ return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
492
+ };
493
+
494
+ exports.__wbg_static_accessor_WINDOW_b45bfc5a37f6cfa2 = function() {
495
+ const ret = typeof window === 'undefined' ? null : window;
496
+ return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
497
+ };
498
+
499
+ exports.__wbg_subarray_480600f3d6a9f26c = function(arg0, arg1, arg2) {
500
+ const ret = arg0.subarray(arg1 >>> 0, arg2 >>> 0);
501
+ return ret;
502
+ };
503
+
504
+ exports.__wbg_versions_c01dfd4722a88165 = function(arg0) {
505
+ const ret = arg0.versions;
506
+ return ret;
507
+ };
508
+
509
+ exports.__wbindgen_cast_2241b6af4c4b2941 = function(arg0, arg1) {
510
+ // Cast intrinsic for `Ref(String) -> Externref`.
511
+ const ret = getStringFromWasm0(arg0, arg1);
512
+ return ret;
513
+ };
514
+
515
+ exports.__wbindgen_cast_cb9088102bce6b30 = function(arg0, arg1) {
516
+ // Cast intrinsic for `Ref(Slice(U8)) -> NamedExternref("Uint8Array")`.
517
+ const ret = getArrayU8FromWasm0(arg0, arg1);
518
+ return ret;
519
+ };
520
+
521
+ exports.__wbindgen_cast_d6cd19b81560fd6e = function(arg0) {
522
+ // Cast intrinsic for `F64 -> Externref`.
523
+ const ret = arg0;
524
+ return ret;
525
+ };
526
+
527
+ exports.__wbindgen_init_externref_table = function() {
528
+ const table = wasm.__wbindgen_externrefs;
529
+ const offset = table.grow(4);
530
+ table.set(0, undefined);
531
+ table.set(offset + 0, undefined);
532
+ table.set(offset + 1, null);
533
+ table.set(offset + 2, true);
534
+ table.set(offset + 3, false);
535
+ ;
536
+ };
537
+
538
+ const wasmPath = `${__dirname}/ballistics_engine_bg.wasm`;
539
+ const wasmBytes = require('fs').readFileSync(wasmPath);
540
+ const wasmModule = new WebAssembly.Module(wasmBytes);
541
+ const wasm = exports.__wasm = new WebAssembly.Instance(wasmModule, imports).exports;
542
+
543
+ wasm.__wbindgen_start();
544
+
Binary file
package/package.json ADDED
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "ballistics-engine",
3
+ "collaborators": [
4
+ "Alex Jokela <email@tinycomputers.io>"
5
+ ],
6
+ "description": "High-performance ballistics trajectory engine with professional physics",
7
+ "version": "0.13.3",
8
+ "license": "MIT OR Apache-2.0",
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "https://github.com/ajokela/ballistics-engine"
12
+ },
13
+ "files": [
14
+ "ballistics_engine_bg.wasm",
15
+ "ballistics_engine.js",
16
+ "ballistics_engine.d.ts"
17
+ ],
18
+ "main": "ballistics_engine.js",
19
+ "homepage": "https://ballistics.rs/",
20
+ "types": "ballistics_engine.d.ts",
21
+ "keywords": [
22
+ "ballistics",
23
+ "trajectory",
24
+ "physics",
25
+ "simulation"
26
+ ]
27
+ }