From 159a09c46172403a7779d9185705354d306f4c87 Mon Sep 17 00:00:00 2001 From: bb1950328 Date: Mon, 3 Oct 2022 20:54:20 +0200 Subject: [PATCH 1/8] start with ballistics calculator add entries for input data enter all data from ABAQUEs --- src/App.vue | 9 +- src/ballistics_data.js | 151 ++++++++++++++++++++++++ src/components/BallisticsCalculator.vue | 76 ++++++++++++ 3 files changed, 234 insertions(+), 2 deletions(-) create mode 100644 src/ballistics_data.js create mode 100644 src/components/BallisticsCalculator.vue diff --git a/src/App.vue b/src/App.vue index c65c8dc..7b67cb8 100644 --- a/src/App.vue +++ b/src/App.vue @@ -10,17 +10,22 @@ + + \ No newline at end of file From 8675a3c3ec5cf759c94ccc6d8ce88b2895e74cc8 Mon Sep 17 00:00:00 2001 From: bb1950328 Date: Fri, 7 Oct 2022 22:28:25 +0200 Subject: [PATCH 2/8] start entering ballistics data start implementing linear interpolation calculations --- src/ballistics_data.js | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/src/ballistics_data.js b/src/ballistics_data.js index 44dbb84..ada3fe4 100644 --- a/src/ballistics_data.js +++ b/src/ballistics_data.js @@ -148,4 +148,41 @@ export const GP04_FLIGHT_TIME = [ [1000, 1.6], [1100, 1.85], [1200, 2.1], -] \ No newline at end of file +]; + +function findLowerHigherRows(table, value0) { + let lowerRow, higherRow; + if (value0 <= table[0][0]) { + lowerRow = table[0]; + higherRow = lowerRow; + } else if (value0 >= table[table.length - 1][0]) { + lowerRow = table[table.length - 1]; + higherRow = lowerRow; + } else { + for (let i = 0; i < table.length; i++) { + if (table[i][0] < value0) { + lowerRow = table[i]; + higherRow = table[i + 1]; + } else if (table[i][0] === value0) { + lowerRow = table[i]; + higherRow = table[i]; + } + } + } + return {lowerRow, higherRow}; +} + +export function lookUpValue1D(table, value0) { + let {lowerRow, higherRow} = findLowerHigherRows(table, value0); + if (lowerRow[0] === higherRow[0]) { + return lowerRow[1]; + } else { + let fraction = (value0 - lowerRow[0]) / (higherRow[0] - lowerRow[0]); + return lowerRow[1] * fraction + higherRow[1] * (1 - fraction); + } +} + +export function lookUpValue2D(table, value0, value1) { + let {lowerRow, higherRow} = findLowerHigherRows(table, value0); + //todo +} \ No newline at end of file From 4320cf4cfe52e20f762aab3d4e0763f5712d12d6 Mon Sep 17 00:00:00 2001 From: bb1950328 Date: Sat, 8 Oct 2022 23:55:06 +0200 Subject: [PATCH 3/8] add classes for 1D, 2D and 3D LUTs partially convert project to typescript --- README.md | 5 + package.json | 17 +- ...{gh-pages-deploy.js => gh-pages-deploy.ts} | 0 src/ballistics_data.js | 188 -------------- src/ballistics_data.ts | 183 ++++++++++++++ src/lookup_table.ts | 140 +++++++++++ src/{main.js => main.ts} | 0 src/{points_list.js => points_list.ts} | 2 +- src/shims-vue.d.ts | 6 + src/{util.js => util.ts} | 81 +++--- tests/unit/lookup_table.test.ts | 35 +++ tests/unit/{util.test.js => util.test.ts} | 4 +- tsconfig.json | 41 ++++ yarn.lock | 231 ++++++++++++++++-- 14 files changed, 679 insertions(+), 254 deletions(-) rename scripts/{gh-pages-deploy.js => gh-pages-deploy.ts} (100%) delete mode 100644 src/ballistics_data.js create mode 100644 src/ballistics_data.ts create mode 100644 src/lookup_table.ts rename src/{main.js => main.ts} (100%) rename src/{points_list.js => points_list.ts} (92%) create mode 100644 src/shims-vue.d.ts rename src/{util.js => util.ts} (55%) create mode 100644 tests/unit/lookup_table.test.ts rename tests/unit/{util.test.js => util.test.ts} (73%) create mode 100644 tsconfig.json diff --git a/README.md b/README.md index 5a71283..c14ad55 100644 --- a/README.md +++ b/README.md @@ -26,5 +26,10 @@ npm run deploy ``` Available at [https://bb1950328.github.io/sph_tool](https://bb1950328.github.io/sph_tool/) +### Runs unittests +``` +npx vitest +``` + ### Customize configuration See [Configuration Reference](https://cli.vuejs.org/config/). diff --git a/package.json b/package.json index 4e661f1..1680f31 100644 --- a/package.json +++ b/package.json @@ -6,9 +6,9 @@ "serve": "vue-cli-service serve", "build": "vue-cli-service build", "lint": "vue-cli-service lint", - "deploy": "node scripts/gh-pages-deploy.js", - "test": "vitest", - "coverage": "vitest run --coverage" + "deploy": "node scripts/gh-pages-deploy.ts", + "coverage": "vitest run --coverage", + "test": "vitest" }, "dependencies": { "@fortawesome/fontawesome-svg-core": "^6.2.0", @@ -18,17 +18,23 @@ "bootstrap": "^5.2.1", "core-js": "^3.8.3", "vue": "^3.2.13", + "vue-class-component": "^8.0.0-0", "vue-the-mask": "^0.11.1" }, "devDependencies": { "@babel/core": "^7.12.16", "@babel/eslint-parser": "^7.12.16", + "@typescript-eslint/eslint-plugin": "^5.4.0", + "@typescript-eslint/parser": "^5.4.0", "@vue/cli-plugin-babel": "~5.0.0", "@vue/cli-plugin-eslint": "~5.0.0", + "@vue/cli-plugin-typescript": "~5.0.0", "@vue/cli-service": "~5.0.0", + "@vue/eslint-config-typescript": "^9.1.0", "eslint": "^7.32.0", "eslint-plugin-vue": "^8.0.3", "execa": "latest", + "typescript": "~4.5.5", "vitest": "^0.23.4" }, "eslintConfig": { @@ -38,10 +44,11 @@ }, "extends": [ "plugin:vue/vue3-essential", - "eslint:recommended" + "eslint:recommended", + "@vue/typescript" ], "parserOptions": { - "parser": "@babel/eslint-parser" + "parser": "@typescript-eslint/parser" }, "rules": {} }, diff --git a/scripts/gh-pages-deploy.js b/scripts/gh-pages-deploy.ts similarity index 100% rename from scripts/gh-pages-deploy.js rename to scripts/gh-pages-deploy.ts diff --git a/src/ballistics_data.js b/src/ballistics_data.js deleted file mode 100644 index ada3fe4..0000000 --- a/src/ballistics_data.js +++ /dev/null @@ -1,188 +0,0 @@ -export const GP04_ELEVATION_CLICKS = [ - [25, 10], - [50, 2], - [75, 0], - [100, 0], - [125, 0], - [150, 2], - [175, 3], - [200, 4], - [225, 4 + 2], - [250, 4 + 4], - [275, 4 + 6], - [300, 11], - [325, 11 + 2], - [350, 11 + 4], - [375, 11 + 6], - - [400, 20], - [425, 20 + 2], - [450, 20 + 5], - [475, 20 + 7], - [500, 29], - [525, 29 + 3], - [550, 29 + 5], - [575, 29 + 8], - [600, 39], - [625, 39 + 3], - [650, 39 + 6], - [675, 39 + 9], - [700, 51], - [725, 51 + 3], - [750, 51 + 6], - [775, 51 + 9], - [800, 63], - [825, 63 + 4], - [850, 63 + 7], - [875, 63 + 11], - [900, 77], - [925, 77 + 4], - [950, 77 + 8], - [975, 77 + 11], - [1000, 92], - [1025, 92 + 4], - [1050, 92 + 9], - [1075, 92 + 13], - [1100, 109], - [1125, 109 + 5], - [1150, 109 + 10], - [1175, 109 + 15], - [1200, 128], - [1225, 128 + 5], - [1250, 128 + 11], - [1275, 128 + 16], -]; -export const GP04_ELEVATION_OLD_BARREL_CORRECTION = [ - [200, 0], - [300, 2], - [400, 1], - [500, 2], - [600, 2], - [700, 2], - [800, 4], - [900, 4], - [1000, 5], - [1100, 6], - [1200, 6], -]; -export const GP04_ELEVATION_AIR_PRESSURE_CORRECTION = [ - [null, 950, 900, 850, 800, 750], - [300, 0, 0, 80, 0, 0], - [400, 0, 0, 80, 0, 0], - [500, -1, -2, -3, -4, -5], - [600, -1, -2, -3, -5, -6], - [700, -2, -3, -5, -6, -7], - [800, -2, -4, -6, -8, -9], - [900, -3, -6, -9, -11, -14], - [1000, -4, -8, -11, -15, -18], - [1100, -5, -9, -13, -17, -20], - [1200, -6, -10, -14, -19, -23], -]; -export const GP04_ELEVATION_TEMPERATURE_CORRECTION = [ - [null, 45, 35, 25, 15, 5, -5, -15, -25], - [300, 0, 0, 0, 0, 0, 0, 0, 0], - [400, 0, 0, 0, 0, 0, 0, 0, 0], - [500, -2, -1, -1, 0, 1, 1, 2, 2], - [600, -2, -1, -1, 0, 1, 1, 2, 3], - [700, -3, -2, -2, 0, 2, 2, 3, 3], - [800, -3, -3, -2, 0, 2, 2, 3, 4], - [900, -4, -3, -2, 0, 2, 3, 4, 5], - [1000, -5, -4, -3, 0, 3, 4, 5, 7], - [1100, -7, -5, -4, 0, 3, 6, 8, 11], - [1200, -9, -6, -5, 0, 4, 8, 10, 15], -]; - -export const GP04_WINDAGE_DERIVATION = [ - [300, 0], - [400, 0], - [500, -1], - [600, -1], - [700, -2], - [800, -2], - [900, -3], - [1000, -3], - [1100, -4], - [1200, -4], -]; -export const GP04_WINDAGE_WIND = [ - [null, null, 2, 4, 6, 8, 10], - [300, 1, 1, 2, 3, 4, 5], - [300, 2, 2, 4, 6, 7, 9], - [300, 3, 2, 4, 6, 9, 11], - [400, 1, 1, 3, 4, 6, 7], - [400, 2, 3, 5, 8, 10, 13], - [400, 3, 3, 6, 9, 12, 15], - [500, 1, 2, 4, 6, 8, 10], - [500, 2, 3, 7, 10, 13, 17], - [500, 3, 4, 8, 12, 15, 19], - [600, 1, 2, 5, 7, 9, 12], - [600, 2, 4, 8, 12, 16, 20], - [600, 3, 5, 9, 14, 19, 23], - [700, 1, 3, 6, 8, 11, 14], - [700, 2, 5, 10, 15, 19, 24], - [700, 3, 6, 11, 17, 23, 28], - [800, 1, 3, 7, 10, 14, 17], - [800, 2, 6, 12, 17, 23, 29], - [800, 3, 7, 14, 20, 27, 34], - [900, 1, 4, 8, 12, 16, 20], - [900, 2, 7, 14, 20, 27, 34], - [900, 3, 8, 16, 24, 32, 39], - [1000, 1, 5, 9, 14, 18, 23], - [1000, 2, 8, 16, 23, 31, 39], - [1000, 3, 9, 18, 27, 36, 45], - [1100, 1, 5, 10, 15, 21, 26], - [1100, 2, 9, 18, 26, 35, 44], - [1100, 3, 10, 21, 31, 41, 51], - [1200, 1, 6, 12, 17, 23, 29], - [1200, 2, 10, 20, 30, 40, 50], - [1200, 3, 12, 23, 35, 46, 58], -]; -export const GP04_FLIGHT_TIME = [ - [300, 0.35], - [400, 0.5], - [500, 0.65], - [600, 0.85], - [700, 1.0], - [800, 1.2], - [900, 1.4], - [1000, 1.6], - [1100, 1.85], - [1200, 2.1], -]; - -function findLowerHigherRows(table, value0) { - let lowerRow, higherRow; - if (value0 <= table[0][0]) { - lowerRow = table[0]; - higherRow = lowerRow; - } else if (value0 >= table[table.length - 1][0]) { - lowerRow = table[table.length - 1]; - higherRow = lowerRow; - } else { - for (let i = 0; i < table.length; i++) { - if (table[i][0] < value0) { - lowerRow = table[i]; - higherRow = table[i + 1]; - } else if (table[i][0] === value0) { - lowerRow = table[i]; - higherRow = table[i]; - } - } - } - return {lowerRow, higherRow}; -} - -export function lookUpValue1D(table, value0) { - let {lowerRow, higherRow} = findLowerHigherRows(table, value0); - if (lowerRow[0] === higherRow[0]) { - return lowerRow[1]; - } else { - let fraction = (value0 - lowerRow[0]) / (higherRow[0] - lowerRow[0]); - return lowerRow[1] * fraction + higherRow[1] * (1 - fraction); - } -} - -export function lookUpValue2D(table, value0, value1) { - let {lowerRow, higherRow} = findLowerHigherRows(table, value0); - //todo -} \ No newline at end of file diff --git a/src/ballistics_data.ts b/src/ballistics_data.ts new file mode 100644 index 0000000..76a3fc6 --- /dev/null +++ b/src/ballistics_data.ts @@ -0,0 +1,183 @@ +import {LookUpTable1D, LookUpTable2D, LookUpTable3D} from "./lookup_table" + +export const GP04_ELEVATION_CLICKS = new LookUpTable1D([ + [25, 10], + [50, 2], + [75, 0], + [100, 0], + [125, 0], + [150, 2], + [175, 3], + [200, 4], + [225, 4 + 2], + [250, 4 + 4], + [275, 4 + 6], + [300, 11], + [325, 11 + 2], + [350, 11 + 4], + [375, 11 + 6], + + [400, 20], + [425, 20 + 2], + [450, 20 + 5], + [475, 20 + 7], + [500, 29], + [525, 29 + 3], + [550, 29 + 5], + [575, 29 + 8], + [600, 39], + [625, 39 + 3], + [650, 39 + 6], + [675, 39 + 9], + [700, 51], + [725, 51 + 3], + [750, 51 + 6], + [775, 51 + 9], + [800, 63], + [825, 63 + 4], + [850, 63 + 7], + [875, 63 + 11], + [900, 77], + [925, 77 + 4], + [950, 77 + 8], + [975, 77 + 11], + [1000, 92], + [1025, 92 + 4], + [1050, 92 + 9], + [1075, 92 + 13], + [1100, 109], + [1125, 109 + 5], + [1150, 109 + 10], + [1175, 109 + 15], + [1200, 128], + [1225, 128 + 5], + [1250, 128 + 11], + [1275, 128 + 16], +]); +export const GP04_ELEVATION_OLD_BARREL_CORRECTION = new LookUpTable1D([ + [200, 0], + [300, 2], + [400, 1], + [500, 2], + [600, 2], + [700, 2], + [800, 4], + [900, 4], + [1000, 5], + [1100, 6], + [1200, 6], +]); +export const GP04_ELEVATION_AIR_PRESSURE_CORRECTION = new LookUpTable2D( + [300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200], + [950, 900, 850, 800, 750], + [ + [0, 0, 0, 0, 0], + [0, 0, 0, 0, 0], + [-1, -2, -3, -4, -5], + [-1, -2, -3, -5, -6], + [-2, -3, -5, -6, -7], + [-2, -4, -6, -8, -9], + [-3, -6, -9, -11, -14], + [-4, -8, -11, -15, -18], + [-5, -9, -13, -17, -20], + [-6, -10, -14, -19, -23], + ]); +export const GP04_ELEVATION_TEMPERATURE_CORRECTION = new LookUpTable2D( + [300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200], + [45, 35, 25, 15, 5, -5, -15, -25], + [ + [0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0], + [-2, -1, -1, 0, 1, 1, 2, 2], + [-2, -1, -1, 0, 1, 1, 2, 3], + [-3, -2, -2, 0, 2, 2, 3, 3], + [-3, -3, -2, 0, 2, 2, 3, 4], + [-4, -3, -2, 0, 2, 3, 4, 5], + [-5, -4, -3, 0, 3, 4, 5, 7], + [-7, -5, -4, 0, 3, 6, 8, 11], + [-9, -6, -5, 0, 4, 8, 10, 15], + ]); + +export const GP04_WINDAGE_DERIVATION = new LookUpTable1D([ + [300, 0], + [400, 0], + [500, -1], + [600, -1], + [700, -2], + [800, -2], + [900, -3], + [1000, -3], + [1100, -4], + [1200, -4], +]); + +export const GP04_WINDAGE_WIND = new LookUpTable3D( + [300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200],//distance + [1, 2, 3],//wind clock + [2, 4, 6, 8, 10],//wind speed + + [ + [//300m + [1, 2, 3, 4, 5], + [2, 4, 6, 7, 9], + [2, 4, 6, 9, 11], + ], + [//400m + [1, 3, 4, 6, 7], + [3, 5, 8, 10, 13], + [3, 6, 9, 12, 15], + ], + [//500m + [2, 4, 6, 8, 10], + [3, 7, 10, 13, 17], + [4, 8, 12, 15, 19], + ], + [//600m + [2, 5, 7, 9, 12], + [4, 8, 12, 16, 20], + [5, 9, 14, 19, 23], + ], + [//700m + [3, 6, 8, 11, 14], + [5, 10, 15, 19, 24], + [6, 11, 17, 23, 28], + ], + [//800m + [3, 7, 10, 14, 17], + [6, 12, 17, 23, 29], + [7, 14, 20, 27, 34], + ], + [//900m + [4, 8, 12, 16, 20], + [7, 14, 20, 27, 34], + [8, 16, 24, 32, 39], + ], + [//1000m + [5, 9, 14, 18, 23], + [8, 16, 23, 31, 39], + [9, 18, 27, 36, 45], + ], + [//1100m + [5, 10, 15, 21, 26], + [9, 18, 26, 35, 44], + [10, 21, 31, 41, 51], + ], + [//1200m + [6, 12, 17, 23, 29], + [10, 20, 30, 40, 50], + [12, 23, 35, 46, 58], + ], + ]); + +export const GP04_FLIGHT_TIME = new LookUpTable1D([ + [300, 0.35], + [400, 0.5], + [500, 0.65], + [600, 0.85], + [700, 1.0], + [800, 1.2], + [900, 1.4], + [1000, 1.6], + [1100, 1.85], + [1200, 2.1], +]); \ No newline at end of file diff --git a/src/lookup_table.ts b/src/lookup_table.ts new file mode 100644 index 0000000..93b74de --- /dev/null +++ b/src/lookup_table.ts @@ -0,0 +1,140 @@ +export class LookUpTableBase { + protected findClosestValueIndex(keys: number[], key: number): number { + let i = 0; + while (keys[i] < key && i < keys.length - 1) { + ++i; + } + const lower = keys[i - 1]; + const upper = keys[i]; + return Math.abs(key - lower) < Math.abs(key - upper) + ? i - 1 + : i; + } + + protected findIndicesAndFactorForInterpolation(keys: number[], key: number): [number, number, number] { + if (key <= keys[0]) { + return [0, 0, 1]; + } else if (key >= keys[keys.length - 1]) { + return [keys.length - 1, keys.length - 1, 1]; + } else { + let i = 0; + while (keys[i] < key && i < keys.length - 1) { + ++i; + } + const lower = keys[i - 1]; + const upper = keys[i]; + return [i - 1, i, (upper - key) / (upper - lower)]; + } + } + + protected checkNotRagged2D(array: any[][]): void { + if (array.length > 0) { + const rowLength = array[0].length; + for (let i = 1; i < array.length; i++) { + if (array[i].length != rowLength) { + throw new Error(`2D array is ragged (starting on row ${i})`); + } + } + } + } +} + +export class LookUpTable1D extends LookUpTableBase { + readonly values: number []; + readonly keys: number[]; + readonly lastIdx: number; + + constructor(rows: number[][]) { + super(); + this.checkNotRagged2D(rows); + this.keys = rows.map(row => row[0]); + this.values = rows.map(row => row[1]); + this.lastIdx = rows.length - 1; + } + + getValueLinearInterpolation(key0: number): number { + const [i0, i1, factor] = this.findIndicesAndFactorForInterpolation(this.keys, key0); + return this.values[i0] * factor + this.values[i1] * (1 - factor); + } + + getClosestValue(key0: number): number { + const i = this.findClosestValueIndex(this.keys, key0); + return this.values[i]; + } +} + +export class LookUpTable2D extends LookUpTableBase { + keys0: number[]; + keys1: number[]; + values: number[][]; + + constructor(keys0: number[], keys1: number[], values: number[][]) { + super(); + this.checkNotRagged2D(values); + this.keys0 = keys0; + this.keys1 = keys1; + this.values = values; + } + + getValueBilinearInterpolation(key0: number, key1: number): number { + const [ix0, ix1, xFactor] = this.findIndicesAndFactorForInterpolation(this.keys0, key0); + const [iy0, iy1, yFactor] = this.findIndicesAndFactorForInterpolation(this.keys1, key1); + const q00 = this.values[ix0][iy0]; + const q01 = this.values[ix0][iy1]; + const q10 = this.values[ix1][iy0]; + const q11 = this.values[ix1][iy1]; + const r0 = q00 * xFactor + q10 * (1 - xFactor); + const r1 = q01 * xFactor + q11 * (1 - xFactor); + return r0 * yFactor + r1 * (1 - yFactor); + } + + getClosestValue(key0: number, key1: number): number { + const i0 = this.findClosestValueIndex(this.keys0, key0); + const i1 = this.findClosestValueIndex(this.keys1, key1); + return this.values[i0][i1]; + } +} + +export class LookUpTable3D extends LookUpTableBase { + keys0: number[]; + keys1: number[]; + keys2: number[]; + values: number[][][]; + + constructor(keys0: number[], keys1: number[], keys2: number[], values: number[][][]) { + super(); + //this.checkNotRagged3D(values); + this.keys0 = keys0; + this.keys1 = keys1; + this.keys2 = keys2; + this.values = values; + } + + getValueTrilinearInterpolation(key0: number, key1: number, key2: number): number { + const [ix0, ix1, xFactor] = this.findIndicesAndFactorForInterpolation(this.keys0, key0); + const [iy0, iy1, yFactor] = this.findIndicesAndFactorForInterpolation(this.keys1, key1); + const [iz0, iz1, zFactor] = this.findIndicesAndFactorForInterpolation(this.keys2, key2); + const q000 = this.values[ix0][iy0][iz0]; + const q010 = this.values[ix0][iy1][iz0]; + const q100 = this.values[ix1][iy0][iz0]; + const q110 = this.values[ix1][iy1][iz0]; + const q001 = this.values[ix0][iy0][iz1]; + const q011 = this.values[ix0][iy1][iz1]; + const q101 = this.values[ix1][iy0][iz1]; + const q111 = this.values[ix1][iy1][iz1]; + const r00 = q000 * xFactor + q100 * (1 - xFactor); + const r10 = q010 * xFactor + q110 * (1 - xFactor); + const r01 = q001 * xFactor + q101 * (1 - xFactor); + const r11 = q011 * xFactor + q111 * (1 - xFactor); + const s0 = r00 * yFactor + r10 * (1 - yFactor); + const s1 = r01 * yFactor + r11 * (1 - yFactor); + return s0 * zFactor + s1 * (1 - zFactor); + } + + getClosestValue(key0: number, key1: number, key2: number): number { + const i0 = this.findClosestValueIndex(this.keys0, key0); + const i1 = this.findClosestValueIndex(this.keys1, key1); + const i2 = this.findClosestValueIndex(this.keys2, key2); + return this.values[i0][i1][i2]; + } +} \ No newline at end of file diff --git a/src/main.js b/src/main.ts similarity index 100% rename from src/main.js rename to src/main.ts diff --git a/src/points_list.js b/src/points_list.ts similarity index 92% rename from src/points_list.js rename to src/points_list.ts index 352e07b..253f4e5 100644 --- a/src/points_list.js +++ b/src/points_list.ts @@ -9,7 +9,7 @@ function storePoints() { } function loadPoints() { - let points = localStorage.getItem("points"); + const points = localStorage.getItem("points"); if (points === null) { return { 1: {"description": "Kaserne Chur", "coordinates": {"x": 758603.97, "y": 190604.61, "z": 582.2}}, diff --git a/src/shims-vue.d.ts b/src/shims-vue.d.ts new file mode 100644 index 0000000..3804a43 --- /dev/null +++ b/src/shims-vue.d.ts @@ -0,0 +1,6 @@ +/* eslint-disable */ +declare module '*.vue' { + import type { DefineComponent } from 'vue' + const component: DefineComponent<{}, {}, any> + export default component +} diff --git a/src/util.js b/src/util.ts similarity index 55% rename from src/util.js rename to src/util.ts index 98e8b2c..1deb9a3 100644 --- a/src/util.js +++ b/src/util.ts @@ -4,26 +4,26 @@ const LV03_Y_MIN = 74_000; const LV03_Y_MAX = 296_000; const LV03_XY_MIDDLE = (LV03_Y_MAX + LV03_X_MIN) / 2; // if a coordinate is below that value, it's more likely to be a Y value, otherwise an X value -export function formatCoordinates(coords) { - let xStr = formatCoordinateXYValue(coords["x"]); - let yStr = formatCoordinateXYValue(coords["y"]); - let zStr = formatCoordinateZValue(coords["z"]); +export function formatCoordinates(coords: { [key: string]: number }): string { + const xStr = formatCoordinateXYValue(coords["x"]); + const yStr = formatCoordinateXYValue(coords["y"]); + const zStr = formatCoordinateZValue(coords["z"]); return `${xStr} / ${yStr} / ${zStr}`; } -export function formatCoordinateXYValue(value) { - let sixDigit = Math.round(value) % 1000000; - let numStr = sixDigit.toString().padStart(6, "0"); +export function formatCoordinateXYValue(value: number): string { + const sixDigit = Math.round(value) % 1000000; + const numStr = sixDigit.toString().padStart(6, "0"); return numStr.slice(0, 3) + " " + numStr.slice(3); } -export function formatCoordinateZValue(value) { +export function formatCoordinateZValue(value: number): string { return Math.round(value).toString(); } -export function formatArtilleryPromilleValue(value) { +export function formatArtilleryPromilleValue(value: number): string { value = Math.round(value); - let valueInRange = ((value % 6400) + 6400) % 6400; + const valueInRange = ((value % 6400) + 6400) % 6400; if (value < 0) { value = valueInRange - 6400; return `${valueInRange}‰ (≙${value}‰)`; @@ -32,55 +32,56 @@ export function formatArtilleryPromilleValue(value) { } } -export function LV03toWGS84(x, y, z) { - let y_aux = (x - 600000) / 1000000; - let x_aux = (y - 200000) / 1000000; - let longitude = 2.6779094 + +export function LV03toWGS84(x: number, y: number, z: number): [number, number, number] { + const y_aux = (x - 600000) / 1000000; + const x_aux = (y - 200000) / 1000000; + const longitude = 2.6779094 + 4.728982 * y_aux + 0.791484 * y_aux * x_aux + 0.1306 * y_aux * Math.pow(x_aux, 2) - 0.0436 * Math.pow(y_aux, 3); - let latitude = 16.9023892 + + const latitude = 16.9023892 + 3.238272 * x_aux - 0.270978 * Math.pow(y_aux, 2) - 0.002528 * Math.pow(x_aux, 2) - 0.0447 * Math.pow(y_aux, 2) * x_aux - 0.0140 * Math.pow(x_aux, 3); - let h = z + 49.55 + const h = z + 49.55 - 12.60 * y_aux - 22.64 * x_aux; return [latitude * 100 / 36, longitude * 100 / 36, h]; } -export function WGS84toLV03(latitude, longitude, height) { - let latitudeTotalSec = latitude * 3600; - let longitudeTotalSec = longitude * 3600; +export function WGS84toLV03(latitude: number, longitude: number, height: number): [number, number, number] { + const latitudeTotalSec = latitude * 3600; + const longitudeTotalSec = longitude * 3600; // https://www.swisstopo.admin.ch/content/swisstopo-internet/en/topics/survey/reference-systems/switzerland/_jcr_content/contentPar/tabs/items/dokumente_publikatio/tabPar/downloadlist/downloadItems/516_1459343097192.download/ch1903wgs84_e.pdf - let latAux = (latitudeTotalSec - 169028.66) / 10000; - let lonAux = (longitudeTotalSec - 26782.5) / 10000; - let e = 2600072.37 + const latAux = (latitudeTotalSec - 169028.66) / 10000; + const lonAux = (longitudeTotalSec - 26782.5) / 10000; + const e = 2600072.37 + 211455.93 * lonAux - 10938.51 * lonAux * latAux - 0.36 * lonAux * Math.pow(lonAux, 2) - 44.54 * Math.pow(lonAux, 3); - let n = 1200147.07 + const n = 1200147.07 + 308807.95 * latAux + 3745.25 * Math.pow(lonAux, 2) + 76.63 * Math.pow(latAux, 2) - 194.56 * Math.pow(lonAux, 2) * latAux + 119.79 * Math.pow(latAux, 3); - let x = e - 2000000; - let y = n - 1000000; - let z = height - 49.55 + const x = e - 2000000; + const y = n - 1000000; + const z = height - 49.55 + 2.73 * lonAux + 6.94 * latAux; return [x, y, z]; } -export function getCurrentPositionLV03(successCallback, errorCallback) { +export function getCurrentPositionLV03(successCallback: (arg0: { [key: string]: number | null }) => void, errorCallback: (arg0: any) => void): void { navigator.geolocation.getCurrentPosition(position => { - let [x, y, z] = WGS84toLV03(position.coords.latitude, position.coords.longitude, position.coords.altitude); - let hasAltitude = position.coords.altitude !== null; + const hasAltitude = position.coords.altitude !== null; + const altitudeOrZero = hasAltitude ? position.coords.altitude : 0; + const [x, y, z] = WGS84toLV03(position.coords.latitude, position.coords.longitude, altitudeOrZero); successCallback({"x": x, "y": y, "z": hasAltitude ? z : null}); }, errorCallback, @@ -91,13 +92,13 @@ export function getCurrentPositionLV03(successCallback, errorCallback) { ); } -export function getHeightFromSwissTopo(x, y, successCallback, errorCallback) { - let params = new URLSearchParams({ - easting: x, - northing: y, - sr: 21781 +export function getHeightFromSwissTopo(x: number, y: number, successCallback: (height: number) => void, errorCallback: (arg0: any) => void): void { + const params = new URLSearchParams({ + easting: x.toString(), + northing: y.toString(), + sr: "21781", }); - let url = "https://api3.geo.admin.ch/rest/services/height?" + params; + const url = "https://api3.geo.admin.ch/rest/services/height?" + params; fetch(url) .then(response => response.json()) .then(json => json["height"]) @@ -105,11 +106,11 @@ export function getHeightFromSwissTopo(x, y, successCallback, errorCallback) { .catch(errorCallback); } -export function extractCoordinatesFromString(text) { +export function extractCoordinatesFromString(text: string): { [key: string]: number } { //todo unit tests for this function - let regex = new RegExp(/[12]?[' ]?(\d{3})[' ]?(\d{3})(\.\d+)?/, "g"); + const regex = new RegExp(/[12]?[' ]?(\d{3})[' ]?(\d{3})(\.\d+)?/, "g"); let rest = text; - let result = {}; + const result: { [key: string]: number } = {}; for (const match of text.matchAll(regex)) { console.log(match[0]); @@ -127,8 +128,8 @@ export function extractCoordinatesFromString(text) { rest = rest.replace(match[0], ""); } - let regexZ = new RegExp(/(\d)[' ]?(\d{2,4})(\.\d+)?/); - let match = regexZ.exec(rest); + const regexZ = new RegExp(/(\d)[' ]?(\d{2,4})(\.\d+)?/); + const match = regexZ.exec(rest); if (match != null) { let number = ""; for (let i = 1; match[i] != null; i++) { diff --git a/tests/unit/lookup_table.test.ts b/tests/unit/lookup_table.test.ts new file mode 100644 index 0000000..825d67f --- /dev/null +++ b/tests/unit/lookup_table.test.ts @@ -0,0 +1,35 @@ +// noinspection ES6PreferShortImport +import {LookUpTable1D} from "../../src/lookup_table"; + +import {expect, test} from "vitest"; + + +test("LUT 1D closestValue", () => { + const lut = new LookUpTable1D([ + [1, 340], + [3, 350], + [4, 356], + [10, 400], + ]); + expect(lut.getClosestValue(1)).eq(340); + expect(lut.getClosestValue(2.1)).eq(350); + expect(lut.getClosestValue(0)).eq(340); + expect(lut.getClosestValue(10)).eq(400); + expect(lut.getClosestValue(13)).eq(400); +}); + +test("LUT 1D interpolation", () => { + const lut = new LookUpTable1D([ + [1, 340], + [3, 350], + [4, 356], + [10, 400], + ]); + expect(lut.getValueLinearInterpolation(0)).eq(340); + expect(lut.getValueLinearInterpolation(1)).eq(340); + expect(lut.getValueLinearInterpolation(2)).closeTo(345, 3); + expect(lut.getValueLinearInterpolation(1.5)).closeTo(342.5, 3); + expect(lut.getValueLinearInterpolation(10)).eq(400); + expect(lut.getValueLinearInterpolation(11)).eq(400); +}); + diff --git a/tests/unit/util.test.js b/tests/unit/util.test.ts similarity index 73% rename from tests/unit/util.test.js rename to tests/unit/util.test.ts index 94cb4ed..7570e0a 100644 --- a/tests/unit/util.test.js +++ b/tests/unit/util.test.ts @@ -4,14 +4,14 @@ import {LV03toWGS84, WGS84toLV03} from "../../src/util"; import {expect, test} from "vitest"; test('WGS84toLV03', () => { - let [x, y, z] = WGS84toLV03(46 + 2 / 60 + 38.87 / 3600, 8 + 43 / 60 + 49.79 / 3600, 650.6); + const [x, y, z] = WGS84toLV03(46 + 2 / 60 + 38.87 / 3600, 8 + 43 / 60 + 49.79 / 3600, 650.6); expect(x).closeTo(699_999.76, 2); expect(y).closeTo(99_999.97, 2); expect(z).closeTo(600.05, 2); }); test("LV03toWGS84", () => { - let [lat, lon, h] = LV03toWGS84(700_000, 100_000, 600); + const [lat, lon, h] = LV03toWGS84(700_000, 100_000, 600); expect(lat).closeTo(46 + 2 / 60 + 38.87 / 3600, 5); expect(lon).closeTo(8 + 43 / 60 + 49.79 / 3600, 5); expect(h).closeTo(650.60, 1); diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..6497d64 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,41 @@ +{ + "compilerOptions": { + "target": "esnext", + "module": "esnext", + "strict": true, + "jsx": "preserve", + "moduleResolution": "node", + "experimentalDecorators": true, + "skipLibCheck": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "forceConsistentCasingInFileNames": true, + "useDefineForClassFields": true, + "sourceMap": true, + "baseUrl": ".", + "types": [ + "webpack-env" + ], + "paths": { + "@/*": [ + "src/*" + ] + }, + "lib": [ + "esnext", + "dom", + "dom.iterable", + "scripthost" + ] + }, + "include": [ + "src/**/*.ts", + "src/**/*.tsx", + "src/**/*.vue", + "tests/**/*.ts", + "tests/**/*.tsx" + ], + "exclude": [ + "node_modules" + ] +} diff --git a/yarn.lock b/yarn.lock index 34a9163..b151427 100644 --- a/yarn.lock +++ b/yarn.lock @@ -26,7 +26,7 @@ dependencies: "@babel/highlight" "^7.10.4" -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.18.6": +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.18.6", "@babel/code-frame@^7.8.3": version "7.18.6" resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz" integrity sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q== @@ -1274,7 +1274,7 @@ dependencies: "@types/node" "*" -"@types/json-schema@*", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": +"@types/json-schema@*", "@types/json-schema@^7.0.4", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": version "7.0.11" resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz" integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== @@ -1341,6 +1341,11 @@ dependencies: "@types/node" "*" +"@types/webpack-env@^1.15.2": + version "1.18.0" + resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.18.0.tgz#ed6ecaa8e5ed5dfe8b2b3d00181702c9925f13fb" + integrity sha512-56/MAlX5WMsPVbOg7tAxnYvNYMMWr/QJiIp6BxVSW3JJXUVzzOn64qW8TzQyMSqSUFM2+PVI4aUHcHOzIz/1tg== + "@types/ws@^8.5.1": version "8.5.3" resolved "https://registry.npmjs.org/@types/ws/-/ws-8.5.3.tgz" @@ -1348,6 +1353,86 @@ dependencies: "@types/node" "*" +"@typescript-eslint/eslint-plugin@^5.4.0": + version "5.39.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.39.0.tgz#778b2d9e7f293502c7feeea6c74dca8eb3e67511" + integrity sha512-xVfKOkBm5iWMNGKQ2fwX5GVgBuHmZBO1tCRwXmY5oAIsPscfwm2UADDuNB8ZVYCtpQvJK4xpjrK7jEhcJ0zY9A== + dependencies: + "@typescript-eslint/scope-manager" "5.39.0" + "@typescript-eslint/type-utils" "5.39.0" + "@typescript-eslint/utils" "5.39.0" + debug "^4.3.4" + ignore "^5.2.0" + regexpp "^3.2.0" + semver "^7.3.7" + tsutils "^3.21.0" + +"@typescript-eslint/parser@^5.4.0": + version "5.39.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.39.0.tgz#93fa0bc980a3a501e081824f6097f7ca30aaa22b" + integrity sha512-PhxLjrZnHShe431sBAGHaNe6BDdxAASDySgsBCGxcBecVCi8NQWxQZMcizNA4g0pN51bBAn/FUfkWG3SDVcGlA== + dependencies: + "@typescript-eslint/scope-manager" "5.39.0" + "@typescript-eslint/types" "5.39.0" + "@typescript-eslint/typescript-estree" "5.39.0" + debug "^4.3.4" + +"@typescript-eslint/scope-manager@5.39.0": + version "5.39.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.39.0.tgz#873e1465afa3d6c78d8ed2da68aed266a08008d0" + integrity sha512-/I13vAqmG3dyqMVSZPjsbuNQlYS082Y7OMkwhCfLXYsmlI0ca4nkL7wJ/4gjX70LD4P8Hnw1JywUVVAwepURBw== + dependencies: + "@typescript-eslint/types" "5.39.0" + "@typescript-eslint/visitor-keys" "5.39.0" + +"@typescript-eslint/type-utils@5.39.0": + version "5.39.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.39.0.tgz#0a8c00f95dce4335832ad2dc6bc431c14e32a0a6" + integrity sha512-KJHJkOothljQWzR3t/GunL0TPKY+fGJtnpl+pX+sJ0YiKTz3q2Zr87SGTmFqsCMFrLt5E0+o+S6eQY0FAXj9uA== + dependencies: + "@typescript-eslint/typescript-estree" "5.39.0" + "@typescript-eslint/utils" "5.39.0" + debug "^4.3.4" + tsutils "^3.21.0" + +"@typescript-eslint/types@5.39.0": + version "5.39.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.39.0.tgz#f4e9f207ebb4579fd854b25c0bf64433bb5ed78d" + integrity sha512-gQMZrnfEBFXK38hYqt8Lkwt8f4U6yq+2H5VDSgP/qiTzC8Nw8JO3OuSUOQ2qW37S/dlwdkHDntkZM6SQhKyPhw== + +"@typescript-eslint/typescript-estree@5.39.0": + version "5.39.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.39.0.tgz#c0316aa04a1a1f4f7f9498e3c13ef1d3dc4cf88b" + integrity sha512-qLFQP0f398sdnogJoLtd43pUgB18Q50QSA+BTE5h3sUxySzbWDpTSdgt4UyxNSozY/oDK2ta6HVAzvGgq8JYnA== + dependencies: + "@typescript-eslint/types" "5.39.0" + "@typescript-eslint/visitor-keys" "5.39.0" + debug "^4.3.4" + globby "^11.1.0" + is-glob "^4.0.3" + semver "^7.3.7" + tsutils "^3.21.0" + +"@typescript-eslint/utils@5.39.0": + version "5.39.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.39.0.tgz#b7063cca1dcf08d1d21b0d91db491161ad0be110" + integrity sha512-+DnY5jkpOpgj+EBtYPyHRjXampJfC0yUZZzfzLuUWVZvCuKqSdJVC8UhdWipIw7VKNTfwfAPiOWzYkAwuIhiAg== + dependencies: + "@types/json-schema" "^7.0.9" + "@typescript-eslint/scope-manager" "5.39.0" + "@typescript-eslint/types" "5.39.0" + "@typescript-eslint/typescript-estree" "5.39.0" + eslint-scope "^5.1.1" + eslint-utils "^3.0.0" + +"@typescript-eslint/visitor-keys@5.39.0": + version "5.39.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.39.0.tgz#8f41f7d241b47257b081ddba5d3ce80deaae61e2" + integrity sha512-yyE3RPwOG+XJBLrhvsxAidUgybJVQ/hG8BhiJo0k8JSAYfk/CshVcxf0HwP4Jt7WZZ6vLmxdo1p6EyN3tzFTkg== + dependencies: + "@typescript-eslint/types" "5.39.0" + eslint-visitor-keys "^3.3.0" + "@vue/babel-helper-vue-jsx-merge-props@^1.4.0": version "1.4.0" resolved "https://registry.npmjs.org/@vue/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-1.4.0.tgz" @@ -1505,6 +1590,21 @@ dependencies: "@vue/cli-shared-utils" "^5.0.8" +"@vue/cli-plugin-typescript@~5.0.0": + version "5.0.8" + resolved "https://registry.yarnpkg.com/@vue/cli-plugin-typescript/-/cli-plugin-typescript-5.0.8.tgz#dd3d2b3a58f3f93359319958dc0f58a4861a33a7" + integrity sha512-JKJOwzJshBqsmp4yLBexwVMebOZ4VGJgbnYvmHVxasJOStF2RxwyW28ZF+zIvASGdat4sAUuo/3mAQyVhm7JHg== + dependencies: + "@babel/core" "^7.12.16" + "@types/webpack-env" "^1.15.2" + "@vue/cli-shared-utils" "^5.0.8" + babel-loader "^8.2.2" + fork-ts-checker-webpack-plugin "^6.4.0" + globby "^11.0.2" + thread-loader "^3.0.0" + ts-loader "^9.2.5" + webpack "^5.54.0" + "@vue/cli-plugin-vuex@^5.0.8": version "5.0.8" resolved "https://registry.npmjs.org/@vue/cli-plugin-vuex/-/cli-plugin-vuex-5.0.8.tgz" @@ -1647,6 +1747,13 @@ optionalDependencies: prettier "^1.18.2 || ^2.0.0" +"@vue/eslint-config-typescript@^9.1.0": + version "9.1.0" + resolved "https://registry.yarnpkg.com/@vue/eslint-config-typescript/-/eslint-config-typescript-9.1.0.tgz#b98a64352b312085444a08b98728962e2a8425ab" + integrity sha512-j/852/ZYQ5wDvCD3HE2q4uqJwJAceer2FwoEch1nFo+zTOsPrbzbE3cuWIs3kvu5hdFsGTMYwRwjI6fqZKDMxQ== + dependencies: + vue-eslint-parser "^8.0.0" + "@vue/reactivity-transform@3.2.40": version "3.2.40" resolved "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.2.40.tgz" @@ -1887,7 +1994,7 @@ ajv-formats@^2.1.1: dependencies: ajv "^8.0.0" -ajv-keywords@^3.5.2: +ajv-keywords@^3.4.1, ajv-keywords@^3.5.2: version "3.5.2" resolved "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz" integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== @@ -1899,7 +2006,7 @@ ajv-keywords@^5.0.0: dependencies: fast-deep-equal "^3.1.3" -ajv@^6.10.0, ajv@^6.12.4, ajv@^6.12.5: +ajv@^6.10.0, ajv@^6.12.2, ajv@^6.12.4, ajv@^6.12.5: version "6.12.6" resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== @@ -2292,7 +2399,7 @@ check-error@^1.0.2: resolved "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz" integrity sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA== -chokidar@^3.5.3: +chokidar@^3.4.2, chokidar@^3.5.3: version "3.5.3" resolved "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz" integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== @@ -2536,6 +2643,17 @@ core-util-is@~1.0.0: resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz" integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== +cosmiconfig@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-6.0.0.tgz#da4fee853c52f6b1e6935f41c1a2fc50bd4a9982" + integrity sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg== + dependencies: + "@types/parse-json" "^4.0.0" + import-fresh "^3.1.0" + parse-json "^5.0.0" + path-type "^4.0.0" + yaml "^1.7.2" + cosmiconfig@^7.0.0: version "7.0.1" resolved "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.1.tgz" @@ -2735,6 +2853,11 @@ deepmerge@^1.5.2: resolved "https://registry.npmjs.org/deepmerge/-/deepmerge-1.5.2.tgz" integrity sha512-95k0GDqvBjZavkuvzx/YqVLv/6YYa17fz6ILMSf7neqQITCPbnfEnQvEgMPNjH4kgobe7+WIL0yJEHku+H3qtQ== +deepmerge@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" + integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== + default-gateway@^6.0.3: version "6.0.3" resolved "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz" @@ -2905,7 +3028,7 @@ end-of-stream@^1.1.0: dependencies: once "^1.4.0" -enhanced-resolve@^5.10.0: +enhanced-resolve@^5.0.0, enhanced-resolve@^5.10.0: version "5.10.0" resolved "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz" integrity sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ== @@ -3470,6 +3593,25 @@ follow-redirects@^1.0.0: resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz" integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== +fork-ts-checker-webpack-plugin@^6.4.0: + version "6.5.2" + resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.2.tgz#4f67183f2f9eb8ba7df7177ce3cf3e75cdafb340" + integrity sha512-m5cUmF30xkZ7h4tWUgTAcEaKmUW7tfyUyTqNNOz7OxWJ0v1VWKTcOvH8FWHUwSjlW/356Ijc9vi3XfcPstpQKA== + dependencies: + "@babel/code-frame" "^7.8.3" + "@types/json-schema" "^7.0.5" + chalk "^4.1.0" + chokidar "^3.4.2" + cosmiconfig "^6.0.0" + deepmerge "^4.2.2" + fs-extra "^9.0.0" + glob "^7.1.6" + memfs "^3.1.2" + minimatch "^3.0.4" + schema-utils "2.7.0" + semver "^7.3.2" + tapable "^1.0.0" + forwarded@0.2.0: version "0.2.0" resolved "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz" @@ -3485,7 +3627,7 @@ fresh@0.5.2: resolved "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz" integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== -fs-extra@^9.1.0: +fs-extra@^9.0.0, fs-extra@^9.1.0: version "9.1.0" resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz" integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== @@ -3580,7 +3722,7 @@ glob-to-regexp@^0.4.1: resolved "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz" integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== -glob@^7.1.3: +glob@^7.1.3, glob@^7.1.6: version "7.2.3" resolved "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz" integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== @@ -3604,9 +3746,9 @@ globals@^13.6.0, globals@^13.9.0: dependencies: type-fest "^0.20.2" -globby@^11.0.2, globby@^11.0.3: +globby@^11.0.2, globby@^11.0.3, globby@^11.1.0: version "11.1.0" - resolved "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== dependencies: array-union "^2.1.0" @@ -3829,7 +3971,7 @@ ignore@^5.2.0: resolved "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz" integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== -import-fresh@^3.0.0, import-fresh@^3.2.1: +import-fresh@^3.0.0, import-fresh@^3.1.0, import-fresh@^3.2.1: version "3.3.0" resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz" integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== @@ -4290,7 +4432,7 @@ media-typer@0.3.0: resolved "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz" integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== -memfs@^3.4.3: +memfs@^3.1.2, memfs@^3.4.3: version "3.4.7" resolved "https://registry.npmjs.org/memfs/-/memfs-3.4.7.tgz" integrity sha512-ygaiUSNalBX85388uskeCyhSAoOSgzBbtVCr9jA2RROssFL9Q19/ZXFqS+2Th2sr1ewNIWgFdLzLC3Yl1Zv+lw== @@ -4324,7 +4466,7 @@ methods@~1.1.2: resolved "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz" integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== -micromatch@^4.0.2, micromatch@^4.0.4, micromatch@^4.0.5: +micromatch@^4.0.0, micromatch@^4.0.2, micromatch@^4.0.4, micromatch@^4.0.5: version "4.0.5" resolved "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz" integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== @@ -5235,9 +5377,9 @@ regenerator-transform@^0.15.0: dependencies: "@babel/runtime" "^7.8.4" -regexpp@^3.1.0: +regexpp@^3.1.0, regexpp@^3.2.0: version "3.2.0" - resolved "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== regexpu-core@^5.1.0: @@ -5371,6 +5513,15 @@ safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.1.0, safe-buffer@~5.2.0: resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== +schema-utils@2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.0.tgz#17151f76d8eae67fbbf77960c33c676ad9f4efc7" + integrity sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A== + dependencies: + "@types/json-schema" "^7.0.4" + ajv "^6.12.2" + ajv-keywords "^3.4.1" + schema-utils@^2.6.5: version "2.7.1" resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz" @@ -5428,6 +5579,13 @@ semver@^7.2.1, semver@^7.3.4, semver@^7.3.5: dependencies: lru-cache "^6.0.0" +semver@^7.3.2, semver@^7.3.7: + version "7.3.8" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.8.tgz#07a78feafb3f7b32347d725e33de7e2a2df67798" + integrity sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A== + dependencies: + lru-cache "^6.0.0" + send@0.18.0: version "0.18.0" resolved "https://registry.npmjs.org/send/-/send-0.18.0.tgz" @@ -5808,6 +5966,11 @@ table@^6.0.9: string-width "^4.2.3" strip-ansi "^6.0.1" +tapable@^1.0.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" + integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== + tapable@^2.0.0, tapable@^2.1.1, tapable@^2.2.0: version "2.2.1" resolved "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz" @@ -5911,11 +6074,33 @@ tr46@~0.0.3: resolved "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz" integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== +ts-loader@^9.2.5: + version "9.4.1" + resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-9.4.1.tgz#b6f3d82db0eac5a8295994f8cb5e4940ff6b1060" + integrity sha512-384TYAqGs70rn9F0VBnh6BPTfhga7yFNdC5gXbQpDrBj9/KsT4iRkGqKXhziofHOlE2j6YEaiTYVGKKvPhGWvw== + dependencies: + chalk "^4.1.0" + enhanced-resolve "^5.0.0" + micromatch "^4.0.0" + semver "^7.3.4" + +tslib@^1.8.1: + version "1.14.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" + integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== + tslib@^2.0.3: version "2.4.0" resolved "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz" integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== +tsutils@^3.21.0: + version "3.21.0" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" + integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== + dependencies: + tslib "^1.8.1" + type-check@^0.4.0, type-check@~0.4.0: version "0.4.0" resolved "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz" @@ -5951,6 +6136,11 @@ type-is@~1.6.18: media-typer "0.3.0" mime-types "~2.1.24" +typescript@~4.5.5: + version "4.5.5" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.5.5.tgz#d8c953832d28924a9e3d37c73d729c846c5896f3" + integrity sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA== + unicode-canonical-property-names-ecmascript@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz" @@ -6066,9 +6256,14 @@ vitest@^0.23.4: tinyspy "^1.0.2" vite "^2.9.12 || ^3.0.0-0" -vue-eslint-parser@^8.0.1: +vue-class-component@^8.0.0-0: + version "8.0.0-rc.1" + resolved "https://registry.yarnpkg.com/vue-class-component/-/vue-class-component-8.0.0-rc.1.tgz#db692cd97656eb9a08206c03d0b7398cdb1d9420" + integrity sha512-w1nMzsT/UdbDAXKqhwTmSoyuJzUXKrxLE77PCFVuC6syr8acdFDAq116xgvZh9UCuV0h+rlCtxXolr3Hi3HyPQ== + +vue-eslint-parser@^8.0.0, vue-eslint-parser@^8.0.1: version "8.3.0" - resolved "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-8.3.0.tgz" + resolved "https://registry.yarnpkg.com/vue-eslint-parser/-/vue-eslint-parser-8.3.0.tgz#5d31129a1b3dd89c0069ca0a1c88f970c360bd0d" integrity sha512-dzHGG3+sYwSf6zFBa0Gi9ZDshD7+ad14DGOdTLjruRVgZXe2J+DcZ9iUhyR48z5g1PqRa20yt3Njna/veLJL/g== dependencies: debug "^4.3.2" @@ -6364,7 +6559,7 @@ yallist@^4.0.0: resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== -yaml@^1.10.0, yaml@^1.10.2: +yaml@^1.10.0, yaml@^1.10.2, yaml@^1.7.2: version "1.10.2" resolved "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz" integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== From 61c5f7c96cdb514afb9b9b07611ddcd0c4d6641c Mon Sep 17 00:00:00 2001 From: bb1950328 Date: Sun, 9 Oct 2022 00:49:07 +0200 Subject: [PATCH 4/8] use LUTs in ballistics calculator tool --- src/ballistics_data.ts | 74 ++++++----- src/components/BallisticsCalculator.vue | 161 +++++++++++++++++++++--- 2 files changed, 183 insertions(+), 52 deletions(-) diff --git a/src/ballistics_data.ts b/src/ballistics_data.ts index 76a3fc6..09c8f37 100644 --- a/src/ballistics_data.ts +++ b/src/ballistics_data.ts @@ -113,59 +113,69 @@ export const GP04_WINDAGE_DERIVATION = new LookUpTable1D([ export const GP04_WINDAGE_WIND = new LookUpTable3D( [300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200],//distance - [1, 2, 3],//wind clock - [2, 4, 6, 8, 10],//wind speed + [0, 1, 2, 3],//wind clock + [0, 2, 4, 6, 8, 10],//wind speed [ [//300m - [1, 2, 3, 4, 5], - [2, 4, 6, 7, 9], - [2, 4, 6, 9, 11], + [0, 0, 0, 0, 0, 0], + [0, 1, 2, 3, 4, 5], + [0, 2, 4, 6, 7, 9], + [0, 2, 4, 6, 9, 11], ], [//400m - [1, 3, 4, 6, 7], - [3, 5, 8, 10, 13], - [3, 6, 9, 12, 15], + [0, 0, 0, 0, 0, 0], + [0, 1, 3, 4, 6, 7], + [0, 3, 5, 8, 10, 13], + [0, 3, 6, 9, 12, 15], ], [//500m - [2, 4, 6, 8, 10], - [3, 7, 10, 13, 17], - [4, 8, 12, 15, 19], + [0, 0, 0, 0, 0, 0], + [0, 2, 4, 6, 8, 10], + [0, 3, 7, 10, 13, 17], + [0, 4, 8, 12, 15, 19], ], [//600m - [2, 5, 7, 9, 12], - [4, 8, 12, 16, 20], - [5, 9, 14, 19, 23], + [0, 0, 0, 0, 0, 0], + [0, 2, 5, 7, 9, 12], + [0, 4, 8, 12, 16, 20], + [0, 5, 9, 14, 19, 23], ], [//700m - [3, 6, 8, 11, 14], - [5, 10, 15, 19, 24], - [6, 11, 17, 23, 28], + [0, 0, 0, 0, 0, 0], + [0, 3, 6, 8, 11, 14], + [0, 5, 10, 15, 19, 24], + [0, 6, 11, 17, 23, 28], ], [//800m - [3, 7, 10, 14, 17], - [6, 12, 17, 23, 29], - [7, 14, 20, 27, 34], + [0, 0, 0, 0, 0, 0], + [0, 3, 7, 10, 14, 17], + [0, 6, 12, 17, 23, 29], + [0, 7, 14, 20, 27, 34], ], [//900m - [4, 8, 12, 16, 20], - [7, 14, 20, 27, 34], - [8, 16, 24, 32, 39], + [0, 0, 0, 0, 0, 0], + [0, 4, 8, 12, 16, 20], + [0, 7, 14, 20, 27, 34], + [0, 8, 16, 24, 32, 39], ], [//1000m - [5, 9, 14, 18, 23], - [8, 16, 23, 31, 39], - [9, 18, 27, 36, 45], + [0, 0, 0, 0, 0, 0], + [0, 5, 9, 14, 18, 23], + [0, 8, 16, 23, 31, 39], + [0, 9, 18, 27, 36, 45], ], [//1100m - [5, 10, 15, 21, 26], - [9, 18, 26, 35, 44], - [10, 21, 31, 41, 51], + [0, 0, 0, 0, 0, 0], + [0, 5, 10, 15, 21, 26], + [0, 9, 18, 26, 35, 44], + [0, 10, 21, 31, 41, 51], ], [//1200m - [6, 12, 17, 23, 29], - [10, 20, 30, 40, 50], - [12, 23, 35, 46, 58], + [0, 0, 0, 0, 0, 0], + [0, 6, 12, 17, 23, 29], + [0, 10, 20, 30, 40, 50], + [0, 12, 23, 35, 46, 58], ], ]); diff --git a/src/components/BallisticsCalculator.vue b/src/components/BallisticsCalculator.vue index 10ffd08..72e34d3 100644 --- a/src/components/BallisticsCalculator.vue +++ b/src/components/BallisticsCalculator.vue @@ -25,21 +25,62 @@ -
- - - - - - - - - -
Höhe{{ formattedElevationClicks }}
Seite{{ formattedWindageClicks }}
+

Resultat

+
+
+ + + + + + + + + + + + + + + + + + + + + +
Distanz{{ alwaysWithSign(resultBaseElevation) }}
Alter Lauf{{ alwaysWithSign(resultOldBarrelElevationCorrection) }}
Luftdruck{{ alwaysWithSign(resultAirPressureElevationCorrection) }}
Temperatur{{ alwaysWithSign(resultTemperatureElevationCorrection) }}
Höhe{{ alwaysWithSign(totalElevationClicks) }}
+
+
+ + + + + + + + + + + + + +
Wind{{ formatWindageClicks(resultBaseWindage) }}
Derivation{{ formatWindageClicks(resultDerivationWindageCorrection) }}
Seite{{ formatWindageClicks(totalWindageClicks) }}
+
\ No newline at end of file From 323bf43159df08b271dd92afe733a5de20887200 Mon Sep 17 00:00:00 2001 From: bb1950328 Date: Mon, 10 Oct 2022 10:30:50 +0200 Subject: [PATCH 5/8] improve BallisticsCalculator: - add old/new barrel radio - add slider for distance - persist and load input values from localStorage --- src/App.vue | 1 - src/components/BallisticsCalculator.vue | 117 ++++++++++++++++-------- 2 files changed, 81 insertions(+), 37 deletions(-) diff --git a/src/App.vue b/src/App.vue index 7b67cb8..58d68e0 100644 --- a/src/App.vue +++ b/src/App.vue @@ -75,7 +75,6 @@ export default { -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; /*background-color: black;*/ - min-height: 100vh; padding: 0.5rem; } diff --git a/src/components/BallisticsCalculator.vue b/src/components/BallisticsCalculator.vue index 72e34d3..c771fbe 100644 --- a/src/components/BallisticsCalculator.vue +++ b/src/components/BallisticsCalculator.vue @@ -1,8 +1,14 @@