ballistics-engine 0.13.3 → 0.25.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.
- package/LICENSE-APACHE +201 -0
- package/README.md +90 -573
- package/ballistics_engine.d.ts +99 -39
- package/ballistics_engine.js +7 -542
- package/ballistics_engine_bg.js +534 -0
- package/ballistics_engine_bg.wasm +0 -0
- package/package.json +18 -6
package/README.md
CHANGED
|
@@ -1,614 +1,131 @@
|
|
|
1
|
-
#
|
|
1
|
+
# ballistics-engine (WASM)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
WebAssembly build of [`ballistics-engine`](https://github.com/ajokela/ballistics-engine), a
|
|
4
|
+
high-performance ballistics trajectory engine (RK4 integration, wind/Coriolis/spin-drift/Magnus
|
|
5
|
+
effects, custom drag tables, Monte Carlo, and more). This package exposes the same CLI-style
|
|
6
|
+
command surface as the native Rust binary, plus a small object-oriented `Calculator` class, to
|
|
7
|
+
JavaScript/TypeScript.
|
|
4
8
|
|
|
5
|
-
|
|
9
|
+
Built with `wasm-pack` and `--no-default-features` — the native crate's default `pdf`/`online`
|
|
10
|
+
features pull in dependencies that don't compile for `wasm32-unknown-unknown`, so the PDF dope-card
|
|
11
|
+
export and the online BC-estimation API are not available from WASM.
|
|
6
12
|
|
|
7
|
-
|
|
13
|
+
> This package is built from `pkg/` (the `wasm-pack --target bundler` output) via
|
|
14
|
+
> `scripts/build-npm.sh` in the source repo. The same script also produces a `pkg-web/` build
|
|
15
|
+
> (`--target web`) for use without a bundler — see "Browser without a bundler" below.
|
|
8
16
|
|
|
9
|
-
|
|
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:
|
|
17
|
+
## Install
|
|
211
18
|
|
|
212
19
|
```bash
|
|
213
|
-
|
|
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
|
|
20
|
+
npm install @SCOPE/ballistics-engine
|
|
217
21
|
```
|
|
218
22
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
### Integration Methods
|
|
23
|
+
`@SCOPE` is a placeholder — see the source repo's `README.md` ("WASM / npm Package" section) for
|
|
24
|
+
the real published name once one exists.
|
|
222
25
|
|
|
223
|
-
|
|
26
|
+
## Quick start (bundler: webpack, Vite, Rollup, Parcel)
|
|
224
27
|
|
|
225
|
-
|
|
226
|
-
-
|
|
28
|
+
This package's `main` entry imports its `.wasm` file as a native ES module, which is how
|
|
29
|
+
`wasm-pack --target bundler` output is meant to be consumed. It works out of the box with Vite and
|
|
30
|
+
Rollup (`@rollup/plugin-wasm`), and with webpack once `experiments.asyncWebAssembly` (or
|
|
31
|
+
`experiments.syncWebAssembly`) is enabled — check your bundler's WASM docs if the import fails.
|
|
227
32
|
|
|
228
|
-
|
|
33
|
+
```js
|
|
34
|
+
import { WasmBallistics } from '@SCOPE/ballistics-engine';
|
|
229
35
|
|
|
230
|
-
|
|
36
|
+
const calc = new WasmBallistics();
|
|
231
37
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
--
|
|
236
|
-
|
|
38
|
+
// The command surface mirrors the native CLI (see CLI_USAGE.md in the source repo for the full
|
|
39
|
+
// flag reference): .308 Winchester, 168gr @ 2700 fps, zeroed at 200 yd, table out to 500 yd.
|
|
40
|
+
const table = calc.runCommand(
|
|
41
|
+
'trajectory -v 2700 -b 0.475 -m 168 -d 0.308 --max-range 500 --auto-zero 200',
|
|
42
|
+
);
|
|
43
|
+
console.log(table);
|
|
237
44
|
```
|
|
238
45
|
|
|
239
|
-
###
|
|
46
|
+
### Custom drag tables (`loadDragTable`)
|
|
240
47
|
|
|
241
|
-
|
|
48
|
+
Supply a measured or manufacturer-published Mach:Cd drag curve (Hornady CDM data, a Lapua/Doppler
|
|
49
|
+
deck, or your own) instead of a G1/G7 model + BC. Once loaded it's applied automatically to every
|
|
50
|
+
`trajectory`, `zero`, `lead`, and `monte-carlo` run — no extra flag needed.
|
|
242
51
|
|
|
243
|
-
```
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
```
|
|
52
|
+
```js
|
|
53
|
+
const csv = 'mach,cd\n0.5,0.220\n0.8,0.230\n1.0,0.520\n1.2,0.480\n1.5,0.400\n2.0,0.330\n2.5,0.300\n';
|
|
54
|
+
calc.loadDragTable(new TextEncoder().encode(csv));
|
|
55
|
+
calc.hasDragTable(); // true
|
|
248
56
|
|
|
249
|
-
|
|
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
|
|
57
|
+
calc.runCommand('trajectory -v 2700 -b 0.475 -m 168 -d 0.308 --max-range 500');
|
|
260
58
|
```
|
|
261
59
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
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
|
-
```
|
|
60
|
+
`loadDragTable` takes raw bytes because WASM has no filesystem access — fetch the CSV yourself
|
|
61
|
+
(`fetch()` in the browser, `fs.readFileSync` in Node) and pass the bytes in. The CSV format is
|
|
62
|
+
documented in the source repo's `CLI_USAGE.md` ("Custom Drag Tables"); a matching
|
|
63
|
+
`loadBc5dTable(bytes)` / `hasBc5dTable()` pair exists for BC5D correction tables.
|
|
272
64
|
|
|
273
|
-
|
|
65
|
+
## Browser without a bundler
|
|
274
66
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
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
|
-
```
|
|
67
|
+
For a plain `<script type="module">` page (no build step), use the `pkg-web/` build instead —
|
|
68
|
+
produced by the same `scripts/build-npm.sh`, and the same build already deployed at
|
|
69
|
+
[ballistics.sh](https://ballistics.sh). It ships an explicit async `init()` you call once before
|
|
70
|
+
constructing `WasmBallistics`:
|
|
293
71
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
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
|
-
```
|
|
72
|
+
```html
|
|
73
|
+
<script type="module">
|
|
74
|
+
import init, { WasmBallistics } from './ballistics_engine.js';
|
|
358
75
|
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
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, ¶ms);
|
|
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);
|
|
76
|
+
await init(); // fetches and instantiates ballistics_engine_bg.wasm relative to this file
|
|
77
|
+
const calc = new WasmBallistics();
|
|
78
|
+
console.log(calc.runCommand('trajectory -v 2700 -b 0.475 -m 168 -d 0.308 --max-range 500'));
|
|
79
|
+
</script>
|
|
387
80
|
```
|
|
388
81
|
|
|
389
|
-
|
|
82
|
+
Serve `ballistics_engine.js` and `ballistics_engine_bg.wasm` from the same directory, and make sure
|
|
83
|
+
your host serves `.wasm` with `Content-Type: application/wasm` (all major static hosts and CDNs do
|
|
84
|
+
this by default).
|
|
390
85
|
|
|
391
|
-
|
|
86
|
+
This `pkg-web/` build is not published to npm as part of this package in the current release —
|
|
87
|
+
it's built locally alongside `pkg/` for direct use or self-hosting. If you need it from npm, either
|
|
88
|
+
vendor the files from `pkg-web/` yourself or publish it as a second package.
|
|
392
89
|
|
|
393
|
-
|
|
394
|
-
- **json** - Complete data in JSON format for programmatic use
|
|
395
|
-
- **csv** - Comma-separated values for spreadsheet analysis
|
|
90
|
+
### Node.js without a bundler
|
|
396
91
|
|
|
397
|
-
|
|
92
|
+
Plain Node `import`/`require` cannot load this package's bundler-target `.wasm` import directly.
|
|
93
|
+
Use the `pkg-web/` build instead, passing the file bytes explicitly (Node's `fetch()` does not
|
|
94
|
+
support `file://` URLs):
|
|
398
95
|
|
|
399
|
-
|
|
96
|
+
```js
|
|
97
|
+
import { readFileSync } from 'node:fs';
|
|
98
|
+
import init, { WasmBallistics } from './pkg-web/ballistics_engine.js';
|
|
400
99
|
|
|
401
|
-
|
|
100
|
+
const wasmBytes = readFileSync(new URL('./pkg-web/ballistics_engine_bg.wasm', import.meta.url));
|
|
101
|
+
await init({ module_or_path: wasmBytes });
|
|
402
102
|
|
|
403
|
-
|
|
404
|
-
|
|
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
|
|
103
|
+
const calc = new WasmBallistics();
|
|
104
|
+
console.log(calc.runCommand('trajectory -v 2700 -b 0.475 -m 168 -d 0.308 --max-range 500'));
|
|
420
105
|
```
|
|
421
106
|
|
|
422
|
-
|
|
107
|
+
If you need a CommonJS (`require()`) Node build, generate one yourself:
|
|
108
|
+
`wasm-pack build --target nodejs --no-default-features`.
|
|
423
109
|
|
|
424
|
-
|
|
110
|
+
## Caveats
|
|
425
111
|
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
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
|
|
112
|
+
- **Size**: the `.wasm` binary is roughly 430 KB (about 175 KB gzipped). It is not code-split or
|
|
113
|
+
lazily loaded — the whole engine loads up front.
|
|
114
|
+
- **Single-threaded**: no SIMD/threads assumptions; no `SharedArrayBuffer` or
|
|
115
|
+
cross-origin-isolation (COOP/COEP) headers required.
|
|
116
|
+
- **No filesystem/network**: table loaders (`loadDragTable`, `loadBc5dTable`) and any file-based
|
|
117
|
+
CLI flags (e.g. native `--drag-table <FILE>`) need the host to fetch bytes and hand them in; see
|
|
118
|
+
`loadDragTable` above.
|
|
119
|
+
- **`pdf`/`online` features are unavailable**: this build excludes them (see above), so
|
|
120
|
+
PDF dope-card export and the online BC-estimation API are not part of the WASM surface.
|
|
121
|
+
- Full API surface (including the `Calculator` builder class) is documented in the bundled
|
|
122
|
+
`.d.ts`; the full CLI flag reference `runCommand` accepts is documented in the source repo's
|
|
123
|
+
`CLI_USAGE.md`.
|
|
599
124
|
|
|
600
125
|
## License
|
|
601
126
|
|
|
602
|
-
|
|
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
|
|
127
|
+
MIT OR Apache-2.0 — see `LICENSE` and `LICENSE-APACHE` in this package.
|
|
610
128
|
|
|
611
|
-
##
|
|
129
|
+
## Source
|
|
612
130
|
|
|
613
|
-
|
|
614
|
-
- GitHub Issues: [github.com/ajokela/ballistics-engine/issues](https://github.com/ajokela/ballistics-engine/issues)
|
|
131
|
+
https://github.com/ajokela/ballistics-engine
|