@orbat-mapper/control-measures 0.2.0-alpha.5 → 0.2.0-alpha.6
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/dist/{index-Ddt-obht.d.mts → index-DUGzYzPy.d.mts} +56 -1
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +17 -2
- package/dist/preview/index.d.mts +1 -1
- package/dist/preview/index.mjs +1 -1
- package/dist/{renderControlMeasure-CDCoQlZ-.mjs → renderControlMeasure-D5NKuws0.mjs} +139 -25
- package/package.json +1 -1
|
@@ -23,6 +23,19 @@ interface ControlMeasureDrawRule {
|
|
|
23
23
|
* `minimumUserPoints` (no early preview).
|
|
24
24
|
*/
|
|
25
25
|
readonly minimumPreviewPoints?: number;
|
|
26
|
+
/**
|
|
27
|
+
* Opt a fixed-length draw into the standard dashed interaction guide. Fixed
|
|
28
|
+
* shapes suppress guides by default because their generator preview is
|
|
29
|
+
* normally sufficient. Use this when the guide communicates an incomplete
|
|
30
|
+
* construction state, such as Rectangle's P1-P2 baseline.
|
|
31
|
+
*/
|
|
32
|
+
readonly showGuide?: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Convert raw draw points into the spine rendered by the interaction guide.
|
|
35
|
+
* Defaults to the raw points. A rule may return the first point again at the
|
|
36
|
+
* end when it needs to provide its own closed guide geometry.
|
|
37
|
+
*/
|
|
38
|
+
guidePoints?(points: readonly Position[]): Position[];
|
|
26
39
|
/**
|
|
27
40
|
* Number of trailing slots in the canonical control-point array that are
|
|
28
41
|
* NOT user-clicked spine vertices. For Axis1, this is 1 (the width handle
|
|
@@ -162,6 +175,18 @@ interface ControlMeasureDefinition<Id extends string, G extends ControlMeasureGe
|
|
|
162
175
|
* ADR-0025.
|
|
163
176
|
*/
|
|
164
177
|
previewSample?: PreviewSample<NonNullable<Parameters<G>[1]>>;
|
|
178
|
+
/**
|
|
179
|
+
* Pins orientation-derived defaults — options whose default value depends on
|
|
180
|
+
* the shape's current screen orientation (e.g. Battle Position's echelon
|
|
181
|
+
* anchor, which defaults to the bottom edge) — to their current concrete
|
|
182
|
+
* values. Returns an options patch to merge onto the working options, or
|
|
183
|
+
* `undefined` when there is nothing to freeze (already frozen, or nothing
|
|
184
|
+
* visible to pin). Called by edit hosts when a rotate gesture starts, so a
|
|
185
|
+
* subsequent rigid rotation of the control points preserves the rendered
|
|
186
|
+
* appearance instead of an orientation-relative default silently re-deriving
|
|
187
|
+
* against the new orientation. See ADR-0023.
|
|
188
|
+
*/
|
|
189
|
+
freezeOrientation?: (controlPoints: Position[], options: NonNullable<Parameters<G>[1]>) => Partial<NonNullable<Parameters<G>[1]>> | undefined;
|
|
165
190
|
}
|
|
166
191
|
/**
|
|
167
192
|
* A measure's representative preview input. Shared between the typed
|
|
@@ -315,6 +340,25 @@ interface BattlePositionOptions {
|
|
|
315
340
|
* @default 0
|
|
316
341
|
*/
|
|
317
342
|
echelonPosition?: number;
|
|
343
|
+
/**
|
|
344
|
+
* Absolute anchor for the echelon glyph, as a fraction of the total
|
|
345
|
+
* perimeter measured from the ring seam (the ring's first vertex), wrapped
|
|
346
|
+
* into `[0, 1)`. When omitted, the anchor is "auto": the bottom edge's
|
|
347
|
+
* midpoint (the side opposite the front), recomputed from the current
|
|
348
|
+
* geometry on every render — the long-standing default behavior.
|
|
349
|
+
* `echelonPosition` still applies on top of this anchor as a signed offset,
|
|
350
|
+
* exactly as it does against the auto anchor.
|
|
351
|
+
*
|
|
352
|
+
* Edit controllers freeze this from "auto" to a concrete fraction the
|
|
353
|
+
* moment a rotate gesture starts (see `freezeEchelonAnchor` /
|
|
354
|
+
* `freezeOrientationOptions`): the transform box rotates only the control
|
|
355
|
+
* points and re-renders, so without a pinned anchor the "bottom edge" would
|
|
356
|
+
* keep re-deriving against the rotated geometry and the glyph would jump to
|
|
357
|
+
* a different edge each time a new edge becomes lowest. Freezing the anchor
|
|
358
|
+
* first makes the rotation rigid — the glyph turns with the shape instead.
|
|
359
|
+
* See ADR-0023.
|
|
360
|
+
*/
|
|
361
|
+
echelonAnchor?: number;
|
|
318
362
|
/**
|
|
319
363
|
* Meters-per-pixel at the current zoom/latitude. Stamped by the host when the
|
|
320
364
|
* measure is screen-anchored; required to resolve `echelonSizePixels`.
|
|
@@ -1505,6 +1549,17 @@ interface RenderOptions {
|
|
|
1505
1549
|
*/
|
|
1506
1550
|
declare function renderControlMeasure<K extends ControlMeasureKind>(cm: ControlMeasure<K>, opts?: RenderOptions): ControlMeasureRender;
|
|
1507
1551
|
//#endregion
|
|
1552
|
+
//#region src/freeze-orientation.d.ts
|
|
1553
|
+
/**
|
|
1554
|
+
* Dispatches to a measure kind's `freezeOrientation` hook (see
|
|
1555
|
+
* {@link import("./define").ControlMeasureDefinition.freezeOrientation}),
|
|
1556
|
+
* pinning orientation-derived option defaults to their current concrete
|
|
1557
|
+
* values ahead of a rigid rotation of `controlPoints`. Returns `undefined`
|
|
1558
|
+
* when the kind declares no hook, or when the hook itself finds nothing to
|
|
1559
|
+
* freeze. Edit hosts call this when a rotate gesture starts (ADR-0023).
|
|
1560
|
+
*/
|
|
1561
|
+
declare function freezeOrientationOptions<K extends ControlMeasureKind>(kind: K, controlPoints: Position[], options: OptionsByKind[K] | undefined): Partial<OptionsByKind[K]> | undefined;
|
|
1562
|
+
//#endregion
|
|
1508
1563
|
//#region src/styleResolver.d.ts
|
|
1509
1564
|
/**
|
|
1510
1565
|
* Three-layer style precedence for `renderControlMeasure`.
|
|
@@ -1767,4 +1822,4 @@ interface TacticalArrowOptions {
|
|
|
1767
1822
|
*/
|
|
1768
1823
|
declare const DEFAULT_TACTICAL_ARROW_OPTIONS: Required<TacticalArrowOptions>;
|
|
1769
1824
|
//#endregion
|
|
1770
|
-
export {
|
|
1825
|
+
export { getControlMeasureMetadata as $, DEFAULT_GENERIC_LINE_OPTIONS as $t, getMetersPerPixel as A, DEFAULT_CANALIZE_OPTIONS as At, ControlMeasureSnapshot as B, DEFAULT_ATTACK_BY_FIRE_OPTIONS as Bt, snapToMidpointPerpendicular as C, ControlMeasureDrawRule as Cn, AntitankDitchOptions as Ct, BaselineFrameOrigin as D, ClearOptions as Dt, BaselineFrameOptions as E, DelayOptions as Et, resolveStyleHints as F, BlockMissionTaskOptions as Ft, cloneControlMeasure as G, AirborneAttackOptions as Gt, StyleHints as H, SupportByFireOptions as Ht, freezeOrientationOptions as I, DEFAULT_BLOCK_MISSION_TASK_OPTIONS as It, CONTROL_MEASURE_IDS as J, GenericCircleOptions as Jt, isKind as K, DEFAULT_AIRBORNE_ATTACK_OPTIONS as Kt, RenderOptions as L, DEFAULT_FLOT_OPTIONS as Lt, SimpleStyleProps as M, DEFAULT_BYPASS_OPTIONS as Mt, SimpleStyleRender as N, BreachOptions as Nt, createBaselineFrame as O, DEFAULT_CLEAR_OPTIONS as Ot, toSimpleStyle as P, DEFAULT_BREACH_OPTIONS as Pt, OptionsByKind as Q, GenericPolygonOptions as Qt, renderControlMeasure as R, FLOTOptions as Rt, pointOnMidpointPerpendicularAxis as S, AnchorTransformEvent as Sn, DEFAULT_ANTITANK_WALL_OPTIONS as St, BaselineFrameNormal as T, DEFAULT_DELAY_OPTIONS as Tt, controlMeasureIdFromFeature as U, AttackHelicopterOptions as Ut, FeaturePartProps as V, DEFAULT_SUPPORT_BY_FIRE_OPTIONS as Vt, ControlMeasure as W, DEFAULT_ATTACK_HELICOPTER_OPTIONS as Wt, ControlMeasureId as X, GenericRectangleOptions as Xt, CONTROL_MEASURE_METADATA as Y, DEFAULT_GENERIC_RECTANGLE_OPTIONS as Yt, ControlMeasureKind as Z, DEFAULT_GENERIC_POLYGON_OPTIONS as Zt, blockDrawRule as _, StrongPointOptions as _n, DEFAULT_FORTIFIED_AREA_OPTIONS as _t, rectangleDrawRule as a, calculateMetrics as an, DEFAULT_OBSTACLE_BYPASS_DIFFICULT_OPTIONS as at, createMidpointPerpendicularDrawRule as b, ControlMeasureMetadata as bn, FortifiedLineOptions as bt, line24DrawRule as c, project as cn, ObstacleBypassEasyOptions as ct, line1DrawRule as d, EncirclementOptions as dn, DEFAULT_FIX_OPTIONS as dt, GenericLineOptions as en, getControlMeasureMetadataByValue as et, ambushDrawRule as f, DEFAULT_FINAL_PROTECTIVE_FIRE_OPTIONS as fn, FixOptions as ft, disruptDrawRule as g, DEFAULT_STRONG_POINT_OPTIONS as gn, DEFAULT_BLOCK_OPTIONS as gt, centerRadiusDrawRule as h, PrincipalDirectionOfFireOptions as hn, BlockOptions as ht, DEFAULT_AMBUSH_OPTIONS as i, MainAttackOptions as in, ObstacleBypassImpossibleOptions as it, roundToFixed as j, BypassOptions as jt, EPSILON as k, CanalizeOptions as kt, line23DrawRule as l, unproject as ln, DEFAULT_TURN_OPTIONS as lt, point12DrawRule as m, DEFAULT_PRINCIPAL_DIRECTION_OF_FIRE_OPTIONS as mn, DisruptOptions as mt, TacticalArrowOptions as n, SupportingAttackOptions as nn, listControlMeasureMetadata as nt, axis1DrawRule as o, computeInitialWidthPoint as on, ObstacleBypassDifficultOptions as ot, attackByFireDrawRule as p, FinalProtectiveFireOptions as pn, DEFAULT_DISRUPT_OPTIONS as pt, ControlMeasureStyle as q, DEFAULT_GENERIC_CIRCLE_OPTIONS as qt, AmbushOptions as r, DEFAULT_MAIN_ATTACK_OPTIONS as rn, DEFAULT_OBSTACLE_BYPASS_IMPOSSIBLE_OPTIONS as rt, supportByFireDrawRule as s, Point2D as sn, DEFAULT_OBSTACLE_BYPASS_EASY_OPTIONS as st, DEFAULT_TACTICAL_ARROW_OPTIONS as t, DEFAULT_SUPPORTING_ATTACK_OPTIONS as tn, getDefaultOptions as tt, turnDrawRule as u, DEFAULT_ENCIRCLEMENT_OPTIONS as un, TurnOptions as ut, MidpointPerpendicularDrawRuleOptions as v, ControlMeasureGeometry as vn, FortifiedAreaOptions as vt, BaselineFrame as w, DEFAULT_ANTITANK_DITCH_OPTIONS as wt, getMidpointPerpendicularSignedDistance as x, ParamDescriptor as xn, AntitankWallOptions as xt, computeDefaultMidpointPerpendicularPoint as y, ControlMeasureGeometryType as yn, DEFAULT_FORTIFIED_LINE_OPTIONS as yt, ControlMeasureRender as z, AttackByFireOptions as zt };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { $ as
|
|
2
|
-
export { type AirborneAttackOptions, type AmbushOptions, type AnchorTransformEvent, type AntitankDitchOptions, type AntitankWallOptions, type AttackByFireOptions, type AttackHelicopterOptions, type BaselineFrame, type BaselineFrameNormal, type BaselineFrameOptions, type BaselineFrameOrigin, type BlockMissionTaskOptions, type BlockOptions, type BreachOptions, type BypassOptions, CONTROL_MEASURE_IDS, CONTROL_MEASURE_METADATA, type CanalizeOptions, type ClearOptions, type ControlMeasure, type ControlMeasureDrawRule, type ControlMeasureGeometry, type ControlMeasureGeometryType, type ControlMeasureId, type ControlMeasureKind, type ControlMeasureMetadata, type ControlMeasureRender, type ControlMeasureSnapshot, type ControlMeasureStyle, DEFAULT_AIRBORNE_ATTACK_OPTIONS, DEFAULT_AMBUSH_OPTIONS, DEFAULT_ANTITANK_DITCH_OPTIONS, DEFAULT_ANTITANK_WALL_OPTIONS, DEFAULT_ATTACK_BY_FIRE_OPTIONS, DEFAULT_ATTACK_HELICOPTER_OPTIONS, DEFAULT_BLOCK_MISSION_TASK_OPTIONS, DEFAULT_BLOCK_OPTIONS, DEFAULT_BREACH_OPTIONS, DEFAULT_BYPASS_OPTIONS, DEFAULT_CANALIZE_OPTIONS, DEFAULT_CLEAR_OPTIONS, DEFAULT_DELAY_OPTIONS, DEFAULT_DISRUPT_OPTIONS, DEFAULT_ENCIRCLEMENT_OPTIONS, DEFAULT_FINAL_PROTECTIVE_FIRE_OPTIONS, DEFAULT_FIX_OPTIONS, DEFAULT_FLOT_OPTIONS, DEFAULT_FORTIFIED_AREA_OPTIONS, DEFAULT_FORTIFIED_LINE_OPTIONS, DEFAULT_GENERIC_CIRCLE_OPTIONS, DEFAULT_GENERIC_LINE_OPTIONS, DEFAULT_GENERIC_POLYGON_OPTIONS, DEFAULT_GENERIC_RECTANGLE_OPTIONS, DEFAULT_MAIN_ATTACK_OPTIONS, DEFAULT_OBSTACLE_BYPASS_DIFFICULT_OPTIONS, DEFAULT_OBSTACLE_BYPASS_EASY_OPTIONS, DEFAULT_OBSTACLE_BYPASS_IMPOSSIBLE_OPTIONS, DEFAULT_PRINCIPAL_DIRECTION_OF_FIRE_OPTIONS, DEFAULT_STRONG_POINT_OPTIONS, DEFAULT_SUPPORTING_ATTACK_OPTIONS, DEFAULT_SUPPORT_BY_FIRE_OPTIONS, DEFAULT_TACTICAL_ARROW_OPTIONS, DEFAULT_TURN_OPTIONS, type DelayOptions, type DisruptOptions, EPSILON, type EncirclementOptions, type FLOTOptions, type FeaturePartProps, type FinalProtectiveFireOptions, type FixOptions, type FortifiedAreaOptions, type FortifiedLineOptions, type GenericCircleOptions, type GenericLineOptions, type GenericPolygonOptions, type GenericRectangleOptions, type MainAttackOptions, type MidpointPerpendicularDrawRuleOptions, type ObstacleBypassDifficultOptions, type ObstacleBypassEasyOptions, type ObstacleBypassImpossibleOptions, type OptionsByKind, type ParamDescriptor, type Point2D, type PrincipalDirectionOfFireOptions, type RenderOptions, type SimpleStyleProps, type SimpleStyleRender, type StrongPointOptions, type StyleHints, type SupportByFireOptions, type SupportingAttackOptions, type TacticalArrowOptions, type TurnOptions, ambushDrawRule, attackByFireDrawRule, axis1DrawRule, blockDrawRule, calculateMetrics, centerRadiusDrawRule, cloneControlMeasure, computeDefaultMidpointPerpendicularPoint, computeInitialWidthPoint, controlMeasureIdFromFeature, createBaselineFrame, createMidpointPerpendicularDrawRule, disruptDrawRule, getControlMeasureMetadata, getControlMeasureMetadataByValue, getDefaultOptions, getMetersPerPixel, getMidpointPerpendicularSignedDistance, isKind, line1DrawRule, line23DrawRule, line24DrawRule, listControlMeasureMetadata, point12DrawRule, pointOnMidpointPerpendicularAxis, project, rectangleDrawRule, renderControlMeasure, resolveStyleHints, roundToFixed, snapToMidpointPerpendicular, supportByFireDrawRule, toSimpleStyle, turnDrawRule, unproject };
|
|
1
|
+
import { $ as getControlMeasureMetadata, $t as DEFAULT_GENERIC_LINE_OPTIONS, A as getMetersPerPixel, At as DEFAULT_CANALIZE_OPTIONS, B as ControlMeasureSnapshot, Bt as DEFAULT_ATTACK_BY_FIRE_OPTIONS, C as snapToMidpointPerpendicular, Cn as ControlMeasureDrawRule, Ct as AntitankDitchOptions, D as BaselineFrameOrigin, Dt as ClearOptions, E as BaselineFrameOptions, Et as DelayOptions, F as resolveStyleHints, Ft as BlockMissionTaskOptions, G as cloneControlMeasure, Gt as AirborneAttackOptions, H as StyleHints, Ht as SupportByFireOptions, I as freezeOrientationOptions, It as DEFAULT_BLOCK_MISSION_TASK_OPTIONS, J as CONTROL_MEASURE_IDS, Jt as GenericCircleOptions, K as isKind, Kt as DEFAULT_AIRBORNE_ATTACK_OPTIONS, L as RenderOptions, Lt as DEFAULT_FLOT_OPTIONS, M as SimpleStyleProps, Mt as DEFAULT_BYPASS_OPTIONS, N as SimpleStyleRender, Nt as BreachOptions, O as createBaselineFrame, Ot as DEFAULT_CLEAR_OPTIONS, P as toSimpleStyle, Pt as DEFAULT_BREACH_OPTIONS, Q as OptionsByKind, Qt as GenericPolygonOptions, R as renderControlMeasure, Rt as FLOTOptions, S as pointOnMidpointPerpendicularAxis, Sn as AnchorTransformEvent, St as DEFAULT_ANTITANK_WALL_OPTIONS, T as BaselineFrameNormal, Tt as DEFAULT_DELAY_OPTIONS, U as controlMeasureIdFromFeature, Ut as AttackHelicopterOptions, V as FeaturePartProps, Vt as DEFAULT_SUPPORT_BY_FIRE_OPTIONS, W as ControlMeasure, Wt as DEFAULT_ATTACK_HELICOPTER_OPTIONS, X as ControlMeasureId, Xt as GenericRectangleOptions, Y as CONTROL_MEASURE_METADATA, Yt as DEFAULT_GENERIC_RECTANGLE_OPTIONS, Z as ControlMeasureKind, Zt as DEFAULT_GENERIC_POLYGON_OPTIONS, _ as blockDrawRule, _n as StrongPointOptions, _t as DEFAULT_FORTIFIED_AREA_OPTIONS, a as rectangleDrawRule, an as calculateMetrics, at as DEFAULT_OBSTACLE_BYPASS_DIFFICULT_OPTIONS, b as createMidpointPerpendicularDrawRule, bn as ControlMeasureMetadata, bt as FortifiedLineOptions, c as line24DrawRule, cn as project, ct as ObstacleBypassEasyOptions, d as line1DrawRule, dn as EncirclementOptions, dt as DEFAULT_FIX_OPTIONS, en as GenericLineOptions, et as getControlMeasureMetadataByValue, f as ambushDrawRule, fn as DEFAULT_FINAL_PROTECTIVE_FIRE_OPTIONS, ft as FixOptions, g as disruptDrawRule, gn as DEFAULT_STRONG_POINT_OPTIONS, gt as DEFAULT_BLOCK_OPTIONS, h as centerRadiusDrawRule, hn as PrincipalDirectionOfFireOptions, ht as BlockOptions, i as DEFAULT_AMBUSH_OPTIONS, in as MainAttackOptions, it as ObstacleBypassImpossibleOptions, j as roundToFixed, jt as BypassOptions, k as EPSILON, kt as CanalizeOptions, l as line23DrawRule, ln as unproject, lt as DEFAULT_TURN_OPTIONS, m as point12DrawRule, mn as DEFAULT_PRINCIPAL_DIRECTION_OF_FIRE_OPTIONS, mt as DisruptOptions, n as TacticalArrowOptions, nn as SupportingAttackOptions, nt as listControlMeasureMetadata, o as axis1DrawRule, on as computeInitialWidthPoint, ot as ObstacleBypassDifficultOptions, p as attackByFireDrawRule, pn as FinalProtectiveFireOptions, pt as DEFAULT_DISRUPT_OPTIONS, q as ControlMeasureStyle, qt as DEFAULT_GENERIC_CIRCLE_OPTIONS, r as AmbushOptions, rn as DEFAULT_MAIN_ATTACK_OPTIONS, rt as DEFAULT_OBSTACLE_BYPASS_IMPOSSIBLE_OPTIONS, s as supportByFireDrawRule, sn as Point2D, st as DEFAULT_OBSTACLE_BYPASS_EASY_OPTIONS, t as DEFAULT_TACTICAL_ARROW_OPTIONS, tn as DEFAULT_SUPPORTING_ATTACK_OPTIONS, tt as getDefaultOptions, u as turnDrawRule, un as DEFAULT_ENCIRCLEMENT_OPTIONS, ut as TurnOptions, v as MidpointPerpendicularDrawRuleOptions, vn as ControlMeasureGeometry, vt as FortifiedAreaOptions, w as BaselineFrame, wt as DEFAULT_ANTITANK_DITCH_OPTIONS, x as getMidpointPerpendicularSignedDistance, xn as ParamDescriptor, xt as AntitankWallOptions, y as computeDefaultMidpointPerpendicularPoint, yn as ControlMeasureGeometryType, yt as DEFAULT_FORTIFIED_LINE_OPTIONS, z as ControlMeasureRender, zt as AttackByFireOptions } from "./index-DUGzYzPy.mjs";
|
|
2
|
+
export { type AirborneAttackOptions, type AmbushOptions, type AnchorTransformEvent, type AntitankDitchOptions, type AntitankWallOptions, type AttackByFireOptions, type AttackHelicopterOptions, type BaselineFrame, type BaselineFrameNormal, type BaselineFrameOptions, type BaselineFrameOrigin, type BlockMissionTaskOptions, type BlockOptions, type BreachOptions, type BypassOptions, CONTROL_MEASURE_IDS, CONTROL_MEASURE_METADATA, type CanalizeOptions, type ClearOptions, type ControlMeasure, type ControlMeasureDrawRule, type ControlMeasureGeometry, type ControlMeasureGeometryType, type ControlMeasureId, type ControlMeasureKind, type ControlMeasureMetadata, type ControlMeasureRender, type ControlMeasureSnapshot, type ControlMeasureStyle, DEFAULT_AIRBORNE_ATTACK_OPTIONS, DEFAULT_AMBUSH_OPTIONS, DEFAULT_ANTITANK_DITCH_OPTIONS, DEFAULT_ANTITANK_WALL_OPTIONS, DEFAULT_ATTACK_BY_FIRE_OPTIONS, DEFAULT_ATTACK_HELICOPTER_OPTIONS, DEFAULT_BLOCK_MISSION_TASK_OPTIONS, DEFAULT_BLOCK_OPTIONS, DEFAULT_BREACH_OPTIONS, DEFAULT_BYPASS_OPTIONS, DEFAULT_CANALIZE_OPTIONS, DEFAULT_CLEAR_OPTIONS, DEFAULT_DELAY_OPTIONS, DEFAULT_DISRUPT_OPTIONS, DEFAULT_ENCIRCLEMENT_OPTIONS, DEFAULT_FINAL_PROTECTIVE_FIRE_OPTIONS, DEFAULT_FIX_OPTIONS, DEFAULT_FLOT_OPTIONS, DEFAULT_FORTIFIED_AREA_OPTIONS, DEFAULT_FORTIFIED_LINE_OPTIONS, DEFAULT_GENERIC_CIRCLE_OPTIONS, DEFAULT_GENERIC_LINE_OPTIONS, DEFAULT_GENERIC_POLYGON_OPTIONS, DEFAULT_GENERIC_RECTANGLE_OPTIONS, DEFAULT_MAIN_ATTACK_OPTIONS, DEFAULT_OBSTACLE_BYPASS_DIFFICULT_OPTIONS, DEFAULT_OBSTACLE_BYPASS_EASY_OPTIONS, DEFAULT_OBSTACLE_BYPASS_IMPOSSIBLE_OPTIONS, DEFAULT_PRINCIPAL_DIRECTION_OF_FIRE_OPTIONS, DEFAULT_STRONG_POINT_OPTIONS, DEFAULT_SUPPORTING_ATTACK_OPTIONS, DEFAULT_SUPPORT_BY_FIRE_OPTIONS, DEFAULT_TACTICAL_ARROW_OPTIONS, DEFAULT_TURN_OPTIONS, type DelayOptions, type DisruptOptions, EPSILON, type EncirclementOptions, type FLOTOptions, type FeaturePartProps, type FinalProtectiveFireOptions, type FixOptions, type FortifiedAreaOptions, type FortifiedLineOptions, type GenericCircleOptions, type GenericLineOptions, type GenericPolygonOptions, type GenericRectangleOptions, type MainAttackOptions, type MidpointPerpendicularDrawRuleOptions, type ObstacleBypassDifficultOptions, type ObstacleBypassEasyOptions, type ObstacleBypassImpossibleOptions, type OptionsByKind, type ParamDescriptor, type Point2D, type PrincipalDirectionOfFireOptions, type RenderOptions, type SimpleStyleProps, type SimpleStyleRender, type StrongPointOptions, type StyleHints, type SupportByFireOptions, type SupportingAttackOptions, type TacticalArrowOptions, type TurnOptions, ambushDrawRule, attackByFireDrawRule, axis1DrawRule, blockDrawRule, calculateMetrics, centerRadiusDrawRule, cloneControlMeasure, computeDefaultMidpointPerpendicularPoint, computeInitialWidthPoint, controlMeasureIdFromFeature, createBaselineFrame, createMidpointPerpendicularDrawRule, disruptDrawRule, freezeOrientationOptions, getControlMeasureMetadata, getControlMeasureMetadataByValue, getDefaultOptions, getMetersPerPixel, getMidpointPerpendicularSignedDistance, isKind, line1DrawRule, line23DrawRule, line24DrawRule, listControlMeasureMetadata, point12DrawRule, pointOnMidpointPerpendicularAxis, project, rectangleDrawRule, renderControlMeasure, resolveStyleHints, roundToFixed, snapToMidpointPerpendicular, supportByFireDrawRule, toSimpleStyle, turnDrawRule, unproject };
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,19 @@
|
|
|
1
|
-
import { $ as point12DrawRule, A as DEFAULT_GENERIC_POLYGON_OPTIONS, B as DEFAULT_ANTITANK_WALL_OPTIONS, C as DEFAULT_FIX_OPTIONS, D as DEFAULT_DELAY_OPTIONS, E as DEFAULT_DISRUPT_OPTIONS, F as DEFAULT_BREACH_OPTIONS, G as axis1DrawRule, H as DEFAULT_AMBUSH_OPTIONS, I as DEFAULT_BLOCK_MISSION_TASK_OPTIONS, J as line23DrawRule, K as supportByFireDrawRule, L as DEFAULT_BLOCK_OPTIONS, M as DEFAULT_GENERIC_CIRCLE_OPTIONS, N as DEFAULT_CANALIZE_OPTIONS, O as DEFAULT_CLEAR_OPTIONS, P as DEFAULT_BYPASS_OPTIONS, Q as attackByFireDrawRule, R as DEFAULT_ATTACK_HELICOPTER_OPTIONS, S as DEFAULT_FLOT_OPTIONS, T as DEFAULT_ENCIRCLEMENT_OPTIONS, U as DEFAULT_AIRBORNE_ATTACK_OPTIONS, V as DEFAULT_ANTITANK_DITCH_OPTIONS, W as rectangleDrawRule, X as line1DrawRule, Y as turnDrawRule, Z as ambushDrawRule, _ as DEFAULT_OBSTACLE_BYPASS_EASY_OPTIONS, at as getMidpointPerpendicularSignedDistance, b as DEFAULT_FORTIFIED_AREA_OPTIONS, c as getDefaultOptions, ct as createBaselineFrame, d as DEFAULT_SUPPORTING_ATTACK_OPTIONS, dt as project, et as centerRadiusDrawRule, f as DEFAULT_SUPPORT_BY_FIRE_OPTIONS, ft as unproject, g as DEFAULT_OBSTACLE_BYPASS_IMPOSSIBLE_OPTIONS, h as DEFAULT_PRINCIPAL_DIRECTION_OF_FIRE_OPTIONS, ht as roundToFixed, i as CONTROL_MEASURE_METADATA, it as createMidpointPerpendicularDrawRule, j as DEFAULT_GENERIC_LINE_OPTIONS, k as DEFAULT_GENERIC_RECTANGLE_OPTIONS, l as listControlMeasureMetadata, lt as calculateMetrics, m as DEFAULT_TACTICAL_ARROW_OPTIONS, mt as getMetersPerPixel, n as resolveStyleHints, nt as blockDrawRule, o as getControlMeasureMetadata, ot as pointOnMidpointPerpendicularAxis, p as DEFAULT_STRONG_POINT_OPTIONS, pt as EPSILON, q as line24DrawRule, r as CONTROL_MEASURE_IDS, rt as computeDefaultMidpointPerpendicularPoint, s as getControlMeasureMetadataByValue, st as snapToMidpointPerpendicular, t as renderControlMeasure, tt as disruptDrawRule, u as DEFAULT_TURN_OPTIONS, ut as computeInitialWidthPoint, v as DEFAULT_OBSTACLE_BYPASS_DIFFICULT_OPTIONS, w as DEFAULT_FINAL_PROTECTIVE_FIRE_OPTIONS, x as DEFAULT_FORTIFIED_LINE_OPTIONS, y as DEFAULT_MAIN_ATTACK_OPTIONS, z as DEFAULT_ATTACK_BY_FIRE_OPTIONS } from "./renderControlMeasure-
|
|
1
|
+
import { $ as point12DrawRule, A as DEFAULT_GENERIC_POLYGON_OPTIONS, B as DEFAULT_ANTITANK_WALL_OPTIONS, C as DEFAULT_FIX_OPTIONS, D as DEFAULT_DELAY_OPTIONS, E as DEFAULT_DISRUPT_OPTIONS, F as DEFAULT_BREACH_OPTIONS, G as axis1DrawRule, H as DEFAULT_AMBUSH_OPTIONS, I as DEFAULT_BLOCK_MISSION_TASK_OPTIONS, J as line23DrawRule, K as supportByFireDrawRule, L as DEFAULT_BLOCK_OPTIONS, M as DEFAULT_GENERIC_CIRCLE_OPTIONS, N as DEFAULT_CANALIZE_OPTIONS, O as DEFAULT_CLEAR_OPTIONS, P as DEFAULT_BYPASS_OPTIONS, Q as attackByFireDrawRule, R as DEFAULT_ATTACK_HELICOPTER_OPTIONS, S as DEFAULT_FLOT_OPTIONS, T as DEFAULT_ENCIRCLEMENT_OPTIONS, U as DEFAULT_AIRBORNE_ATTACK_OPTIONS, V as DEFAULT_ANTITANK_DITCH_OPTIONS, W as rectangleDrawRule, X as line1DrawRule, Y as turnDrawRule, Z as ambushDrawRule, _ as DEFAULT_OBSTACLE_BYPASS_EASY_OPTIONS, a as DEFINITIONS, at as getMidpointPerpendicularSignedDistance, b as DEFAULT_FORTIFIED_AREA_OPTIONS, c as getDefaultOptions, ct as createBaselineFrame, d as DEFAULT_SUPPORTING_ATTACK_OPTIONS, dt as project, et as centerRadiusDrawRule, f as DEFAULT_SUPPORT_BY_FIRE_OPTIONS, ft as unproject, g as DEFAULT_OBSTACLE_BYPASS_IMPOSSIBLE_OPTIONS, h as DEFAULT_PRINCIPAL_DIRECTION_OF_FIRE_OPTIONS, ht as roundToFixed, i as CONTROL_MEASURE_METADATA, it as createMidpointPerpendicularDrawRule, j as DEFAULT_GENERIC_LINE_OPTIONS, k as DEFAULT_GENERIC_RECTANGLE_OPTIONS, l as listControlMeasureMetadata, lt as calculateMetrics, m as DEFAULT_TACTICAL_ARROW_OPTIONS, mt as getMetersPerPixel, n as resolveStyleHints, nt as blockDrawRule, o as getControlMeasureMetadata, ot as pointOnMidpointPerpendicularAxis, p as DEFAULT_STRONG_POINT_OPTIONS, pt as EPSILON, q as line24DrawRule, r as CONTROL_MEASURE_IDS, rt as computeDefaultMidpointPerpendicularPoint, s as getControlMeasureMetadataByValue, st as snapToMidpointPerpendicular, t as renderControlMeasure, tt as disruptDrawRule, u as DEFAULT_TURN_OPTIONS, ut as computeInitialWidthPoint, v as DEFAULT_OBSTACLE_BYPASS_DIFFICULT_OPTIONS, w as DEFAULT_FINAL_PROTECTIVE_FIRE_OPTIONS, x as DEFAULT_FORTIFIED_LINE_OPTIONS, y as DEFAULT_MAIN_ATTACK_OPTIONS, z as DEFAULT_ATTACK_BY_FIRE_OPTIONS } from "./renderControlMeasure-D5NKuws0.mjs";
|
|
2
|
+
//#region src/freeze-orientation.ts
|
|
3
|
+
/**
|
|
4
|
+
* Dispatches to a measure kind's `freezeOrientation` hook (see
|
|
5
|
+
* {@link import("./define").ControlMeasureDefinition.freezeOrientation}),
|
|
6
|
+
* pinning orientation-derived option defaults to their current concrete
|
|
7
|
+
* values ahead of a rigid rotation of `controlPoints`. Returns `undefined`
|
|
8
|
+
* when the kind declares no hook, or when the hook itself finds nothing to
|
|
9
|
+
* freeze. Edit hosts call this when a rotate gesture starts (ADR-0023).
|
|
10
|
+
*/
|
|
11
|
+
function freezeOrientationOptions(kind, controlPoints, options) {
|
|
12
|
+
const definition = DEFINITIONS[kind];
|
|
13
|
+
if (!definition.freezeOrientation) return void 0;
|
|
14
|
+
return definition.freezeOrientation(controlPoints, options ?? {});
|
|
15
|
+
}
|
|
16
|
+
//#endregion
|
|
2
17
|
//#region src/instance.ts
|
|
3
18
|
function isKind(cm, kind) {
|
|
4
19
|
return cm.kind === kind;
|
|
@@ -99,4 +114,4 @@ function toHexChannel(value) {
|
|
|
99
114
|
return Math.max(0, Math.min(255, Math.round(value))).toString(16).padStart(2, "0");
|
|
100
115
|
}
|
|
101
116
|
//#endregion
|
|
102
|
-
export { CONTROL_MEASURE_IDS, CONTROL_MEASURE_METADATA, DEFAULT_AIRBORNE_ATTACK_OPTIONS, DEFAULT_AMBUSH_OPTIONS, DEFAULT_ANTITANK_DITCH_OPTIONS, DEFAULT_ANTITANK_WALL_OPTIONS, DEFAULT_ATTACK_BY_FIRE_OPTIONS, DEFAULT_ATTACK_HELICOPTER_OPTIONS, DEFAULT_BLOCK_MISSION_TASK_OPTIONS, DEFAULT_BLOCK_OPTIONS, DEFAULT_BREACH_OPTIONS, DEFAULT_BYPASS_OPTIONS, DEFAULT_CANALIZE_OPTIONS, DEFAULT_CLEAR_OPTIONS, DEFAULT_DELAY_OPTIONS, DEFAULT_DISRUPT_OPTIONS, DEFAULT_ENCIRCLEMENT_OPTIONS, DEFAULT_FINAL_PROTECTIVE_FIRE_OPTIONS, DEFAULT_FIX_OPTIONS, DEFAULT_FLOT_OPTIONS, DEFAULT_FORTIFIED_AREA_OPTIONS, DEFAULT_FORTIFIED_LINE_OPTIONS, DEFAULT_GENERIC_CIRCLE_OPTIONS, DEFAULT_GENERIC_LINE_OPTIONS, DEFAULT_GENERIC_POLYGON_OPTIONS, DEFAULT_GENERIC_RECTANGLE_OPTIONS, DEFAULT_MAIN_ATTACK_OPTIONS, DEFAULT_OBSTACLE_BYPASS_DIFFICULT_OPTIONS, DEFAULT_OBSTACLE_BYPASS_EASY_OPTIONS, DEFAULT_OBSTACLE_BYPASS_IMPOSSIBLE_OPTIONS, DEFAULT_PRINCIPAL_DIRECTION_OF_FIRE_OPTIONS, DEFAULT_STRONG_POINT_OPTIONS, DEFAULT_SUPPORTING_ATTACK_OPTIONS, DEFAULT_SUPPORT_BY_FIRE_OPTIONS, DEFAULT_TACTICAL_ARROW_OPTIONS, DEFAULT_TURN_OPTIONS, EPSILON, ambushDrawRule, attackByFireDrawRule, axis1DrawRule, blockDrawRule, calculateMetrics, centerRadiusDrawRule, cloneControlMeasure, computeDefaultMidpointPerpendicularPoint, computeInitialWidthPoint, controlMeasureIdFromFeature, createBaselineFrame, createMidpointPerpendicularDrawRule, disruptDrawRule, getControlMeasureMetadata, getControlMeasureMetadataByValue, getDefaultOptions, getMetersPerPixel, getMidpointPerpendicularSignedDistance, isKind, line1DrawRule, line23DrawRule, line24DrawRule, listControlMeasureMetadata, point12DrawRule, pointOnMidpointPerpendicularAxis, project, rectangleDrawRule, renderControlMeasure, resolveStyleHints, roundToFixed, snapToMidpointPerpendicular, supportByFireDrawRule, toSimpleStyle, turnDrawRule, unproject };
|
|
117
|
+
export { CONTROL_MEASURE_IDS, CONTROL_MEASURE_METADATA, DEFAULT_AIRBORNE_ATTACK_OPTIONS, DEFAULT_AMBUSH_OPTIONS, DEFAULT_ANTITANK_DITCH_OPTIONS, DEFAULT_ANTITANK_WALL_OPTIONS, DEFAULT_ATTACK_BY_FIRE_OPTIONS, DEFAULT_ATTACK_HELICOPTER_OPTIONS, DEFAULT_BLOCK_MISSION_TASK_OPTIONS, DEFAULT_BLOCK_OPTIONS, DEFAULT_BREACH_OPTIONS, DEFAULT_BYPASS_OPTIONS, DEFAULT_CANALIZE_OPTIONS, DEFAULT_CLEAR_OPTIONS, DEFAULT_DELAY_OPTIONS, DEFAULT_DISRUPT_OPTIONS, DEFAULT_ENCIRCLEMENT_OPTIONS, DEFAULT_FINAL_PROTECTIVE_FIRE_OPTIONS, DEFAULT_FIX_OPTIONS, DEFAULT_FLOT_OPTIONS, DEFAULT_FORTIFIED_AREA_OPTIONS, DEFAULT_FORTIFIED_LINE_OPTIONS, DEFAULT_GENERIC_CIRCLE_OPTIONS, DEFAULT_GENERIC_LINE_OPTIONS, DEFAULT_GENERIC_POLYGON_OPTIONS, DEFAULT_GENERIC_RECTANGLE_OPTIONS, DEFAULT_MAIN_ATTACK_OPTIONS, DEFAULT_OBSTACLE_BYPASS_DIFFICULT_OPTIONS, DEFAULT_OBSTACLE_BYPASS_EASY_OPTIONS, DEFAULT_OBSTACLE_BYPASS_IMPOSSIBLE_OPTIONS, DEFAULT_PRINCIPAL_DIRECTION_OF_FIRE_OPTIONS, DEFAULT_STRONG_POINT_OPTIONS, DEFAULT_SUPPORTING_ATTACK_OPTIONS, DEFAULT_SUPPORT_BY_FIRE_OPTIONS, DEFAULT_TACTICAL_ARROW_OPTIONS, DEFAULT_TURN_OPTIONS, EPSILON, ambushDrawRule, attackByFireDrawRule, axis1DrawRule, blockDrawRule, calculateMetrics, centerRadiusDrawRule, cloneControlMeasure, computeDefaultMidpointPerpendicularPoint, computeInitialWidthPoint, controlMeasureIdFromFeature, createBaselineFrame, createMidpointPerpendicularDrawRule, disruptDrawRule, freezeOrientationOptions, getControlMeasureMetadata, getControlMeasureMetadataByValue, getDefaultOptions, getMetersPerPixel, getMidpointPerpendicularSignedDistance, isKind, line1DrawRule, line23DrawRule, line24DrawRule, listControlMeasureMetadata, point12DrawRule, pointOnMidpointPerpendicularAxis, project, rectangleDrawRule, renderControlMeasure, resolveStyleHints, roundToFixed, snapToMidpointPerpendicular, supportByFireDrawRule, toSimpleStyle, turnDrawRule, unproject };
|
package/dist/preview/index.d.mts
CHANGED
package/dist/preview/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as DEFINITIONS, t as renderControlMeasure } from "../renderControlMeasure-
|
|
1
|
+
import { a as DEFINITIONS, t as renderControlMeasure } from "../renderControlMeasure-D5NKuws0.mjs";
|
|
2
2
|
//#region src/preview/index.ts
|
|
3
3
|
/**
|
|
4
4
|
* Unitless `previewSample` points (~`[-1, 1]`) are scaled by this degree offset
|
|
@@ -849,19 +849,91 @@ const searchAreaDrawRule = {
|
|
|
849
849
|
//#endregion
|
|
850
850
|
//#region src/draw-rules/rectangle.ts
|
|
851
851
|
/**
|
|
852
|
-
*
|
|
853
|
-
*
|
|
852
|
+
* Oriented rectangle: P1 and P2 are adjacent corners and define the first
|
|
853
|
+
* edge. P3 is the next corner, constrained to the perpendicular through P2.
|
|
854
|
+
* The generator derives the fourth corner.
|
|
854
855
|
*/
|
|
855
856
|
function derive(points) {
|
|
856
|
-
|
|
857
|
+
if (points.length < 2) return clonePositions(points);
|
|
858
|
+
const p1 = clonePosition(points[0]);
|
|
859
|
+
const p2 = clonePosition(points[1]);
|
|
860
|
+
if (points.length === 2) return [
|
|
861
|
+
p1,
|
|
862
|
+
p2,
|
|
863
|
+
clonePosition(p2)
|
|
864
|
+
];
|
|
865
|
+
const frame = createBaselineFrame(p1, p2, {
|
|
866
|
+
origin: "p2",
|
|
867
|
+
normal: "right"
|
|
868
|
+
});
|
|
869
|
+
return [
|
|
870
|
+
p1,
|
|
871
|
+
p2,
|
|
872
|
+
frame?.pointAtNormalDistance(frame.signedNormalDistance(points[2])) ?? clonePosition(points[2])
|
|
873
|
+
];
|
|
874
|
+
}
|
|
875
|
+
function guidePoints(points) {
|
|
876
|
+
const canonical = derive(points);
|
|
877
|
+
if (canonical.length < 3) return canonical;
|
|
878
|
+
const [c1, c2, c3] = canonical;
|
|
879
|
+
if (!c1 || !c2 || !c3) return canonical;
|
|
880
|
+
if (c2[0] === c3[0] && c2[1] === c3[1]) return [c1, c2];
|
|
881
|
+
const p1 = project(c1[0], c1[1]);
|
|
882
|
+
const p2 = project(c2[0], c2[1]);
|
|
883
|
+
const p4 = vecAdd(p1, vecSub(project(c3[0], c3[1]), p2));
|
|
884
|
+
return [
|
|
885
|
+
c1,
|
|
886
|
+
c2,
|
|
887
|
+
c3,
|
|
888
|
+
unproject(p4[0], p4[1]),
|
|
889
|
+
clonePosition(c1)
|
|
890
|
+
];
|
|
891
|
+
}
|
|
892
|
+
function snapToAxis(point, origin, direction) {
|
|
893
|
+
const snapped = vecAdd(origin, vecScale(direction, vecDot(vecSub(project(point[0], point[1]), origin), direction)));
|
|
894
|
+
return unproject(snapped[0], snapped[1]);
|
|
857
895
|
}
|
|
858
896
|
const rectangleDrawRule = {
|
|
859
897
|
id: "rectangle",
|
|
860
|
-
minimumUserPoints:
|
|
861
|
-
|
|
898
|
+
minimumUserPoints: 3,
|
|
899
|
+
minimumPreviewPoints: 2,
|
|
900
|
+
canonicalPointCount: 3,
|
|
901
|
+
showGuide: true,
|
|
902
|
+
guidePoints,
|
|
862
903
|
derive,
|
|
863
904
|
transform(event) {
|
|
864
|
-
|
|
905
|
+
const { previous, next, activePointIndex } = event;
|
|
906
|
+
if (previous.length < 3 || next.length < 3) return derive(next);
|
|
907
|
+
const frame = createBaselineFrame(previous[0], previous[1], {
|
|
908
|
+
origin: "p2",
|
|
909
|
+
normal: "right"
|
|
910
|
+
});
|
|
911
|
+
if (!frame) return derive(next);
|
|
912
|
+
if (activePointIndex === 0) return [
|
|
913
|
+
snapToAxis(next[0], frame.p2, frame.direction),
|
|
914
|
+
clonePosition(previous[1]),
|
|
915
|
+
clonePosition(previous[2])
|
|
916
|
+
];
|
|
917
|
+
if (activePointIndex === 1) {
|
|
918
|
+
const p2 = snapToAxis(next[1], frame.p1, frame.direction);
|
|
919
|
+
const delta = vecSub(project(p2[0], p2[1]), frame.p2);
|
|
920
|
+
const projectedP3 = vecAdd(project(previous[2][0], previous[2][1]), delta);
|
|
921
|
+
const p3 = unproject(projectedP3[0], projectedP3[1]);
|
|
922
|
+
return [
|
|
923
|
+
clonePosition(previous[0]),
|
|
924
|
+
p2,
|
|
925
|
+
p3
|
|
926
|
+
];
|
|
927
|
+
}
|
|
928
|
+
if (activePointIndex === 2) {
|
|
929
|
+
const p3 = frame.pointAtNormalDistance(frame.signedNormalDistance(next[2]));
|
|
930
|
+
if (p3) return [
|
|
931
|
+
clonePosition(previous[0]),
|
|
932
|
+
clonePosition(previous[1]),
|
|
933
|
+
p3
|
|
934
|
+
];
|
|
935
|
+
}
|
|
936
|
+
return derive(next);
|
|
865
937
|
}
|
|
866
938
|
};
|
|
867
939
|
//#endregion
|
|
@@ -2351,13 +2423,21 @@ function resolveEchelonHeight(echelonSize, echelonSizePixels, metersPerPixel) {
|
|
|
2351
2423
|
if (echelonSizePixels !== void 0 && metersPerPixel !== void 0 && metersPerPixel > 0) h = echelonSizePixels * metersPerPixel;
|
|
2352
2424
|
return Math.max(EPSILON, h);
|
|
2353
2425
|
}
|
|
2426
|
+
/** Wraps `x` into `[0, 1)`, treating `x` as a fraction (matches the arc-length wrap below). */
|
|
2427
|
+
function wrap01(x) {
|
|
2428
|
+
return (x % 1 + 1) % 1;
|
|
2429
|
+
}
|
|
2354
2430
|
/**
|
|
2355
2431
|
* Places the Field B echelon glyph on the perimeter and computes its masking
|
|
2356
|
-
* gap, anchored to the bottom edge and slid by `echelonPosition`
|
|
2357
|
-
* fraction of the perimeter, wrapping at the seam).
|
|
2358
|
-
*
|
|
2432
|
+
* gap, anchored by default to the bottom edge and slid by `echelonPosition`
|
|
2433
|
+
* (a signed fraction of the perimeter, wrapping at the seam). When
|
|
2434
|
+
* `echelonAnchor` is supplied, it replaces the bottom-edge anchor with an
|
|
2435
|
+
* absolute perimeter fraction (measured from the ring seam) — see
|
|
2436
|
+
* `BattlePositionOptions.echelonAnchor` for why (ADR-0023 rotate-freeze).
|
|
2437
|
+
* Returns empty geometry when the echelon resolves to none or the ring is
|
|
2438
|
+
* degenerate.
|
|
2359
2439
|
*/
|
|
2360
|
-
function placeEchelon(perimeter, h, echelon, echelonPadding, echelonPosition) {
|
|
2440
|
+
function placeEchelon(perimeter, h, echelon, echelonPadding, echelonPosition, echelonAnchor) {
|
|
2361
2441
|
const { segs, totalLength, anchorTarget } = perimeter;
|
|
2362
2442
|
const spec = resolveEchelon(echelon);
|
|
2363
2443
|
if (!spec || segs.length === 0 || totalLength < 1e-6) return {
|
|
@@ -2365,7 +2445,7 @@ function placeEchelon(perimeter, h, echelon, echelonPadding, echelonPosition) {
|
|
|
2365
2445
|
fills: [],
|
|
2366
2446
|
gaps: []
|
|
2367
2447
|
};
|
|
2368
|
-
const target = ((anchorTarget + echelonPosition * totalLength) % totalLength + totalLength) % totalLength;
|
|
2448
|
+
const target = (((echelonAnchor !== void 0 ? wrap01(echelonAnchor) * totalLength : anchorTarget) + echelonPosition * totalLength) % totalLength + totalLength) % totalLength;
|
|
2369
2449
|
const { point, seg } = pointOnRing(segs, target);
|
|
2370
2450
|
const { strokes, fills, width } = buildEchelonGlyph(point, seg.along, seg.perp, h, spec);
|
|
2371
2451
|
const gaps = [];
|
|
@@ -2475,10 +2555,10 @@ const BATTLE_POSITION_METADATA = {
|
|
|
2475
2555
|
* @param options - {@link BattlePositionOptions}.
|
|
2476
2556
|
*/
|
|
2477
2557
|
function createBattlePosition(positions, options = {}) {
|
|
2478
|
-
const { echelon = DEFAULT_BATTLE_POSITION_OPTIONS.echelon, echelonSize = DEFAULT_BATTLE_POSITION_OPTIONS.echelonSize, echelonSizePixels, echelonPadding = DEFAULT_BATTLE_POSITION_OPTIONS.echelonPadding, echelonPosition = DEFAULT_BATTLE_POSITION_OPTIONS.echelonPosition, metersPerPixel, smooth = DEFAULT_BATTLE_POSITION_OPTIONS.smooth, smoothResolution = DEFAULT_BATTLE_POSITION_OPTIONS.smoothResolution } = options;
|
|
2558
|
+
const { echelon = DEFAULT_BATTLE_POSITION_OPTIONS.echelon, echelonSize = DEFAULT_BATTLE_POSITION_OPTIONS.echelonSize, echelonSizePixels, echelonPadding = DEFAULT_BATTLE_POSITION_OPTIONS.echelonPadding, echelonPosition = DEFAULT_BATTLE_POSITION_OPTIONS.echelonPosition, echelonAnchor, metersPerPixel, smooth = DEFAULT_BATTLE_POSITION_OPTIONS.smooth, smoothResolution = DEFAULT_BATTLE_POSITION_OPTIONS.smoothResolution } = options;
|
|
2479
2559
|
const h = resolveEchelonHeight(echelonSize, echelonSizePixels, metersPerPixel);
|
|
2480
2560
|
const verts = buildClosedRing(positions, smooth, smoothResolution, DEFAULT_SMOOTH_RESOLUTION$6);
|
|
2481
|
-
const { strokes, fills, gaps } = placeEchelon(buildAreaPerimeter(verts), h, echelon, echelonPadding, echelonPosition);
|
|
2561
|
+
const { strokes, fills, gaps } = placeEchelon(buildAreaPerimeter(verts), h, echelon, echelonPadding, echelonPosition, echelonAnchor);
|
|
2482
2562
|
const boundaryCoords = buildGappedLine(verts, gaps);
|
|
2483
2563
|
const features = [];
|
|
2484
2564
|
if (boundaryCoords.length > 0) features.push({
|
|
@@ -2513,11 +2593,29 @@ function createBattlePosition(positions, options = {}) {
|
|
|
2513
2593
|
features
|
|
2514
2594
|
};
|
|
2515
2595
|
}
|
|
2596
|
+
/**
|
|
2597
|
+
* `freezeOrientation` hook (ADR-0023) shared by Battle Position and Strong
|
|
2598
|
+
* Point: pins the echelon anchor to its current bottom-edge fraction so a
|
|
2599
|
+
* subsequent rigid rotation of `controlPoints` (e.g. the transform box's
|
|
2600
|
+
* rotate grip) does not re-derive a different "bottom edge" against the
|
|
2601
|
+
* rotated geometry. Returns `undefined` — nothing to freeze — when:
|
|
2602
|
+
* - `echelonAnchor` is already set (previously frozen or user-authored), or
|
|
2603
|
+
* - the echelon resolves to none (nothing visible to pin), or
|
|
2604
|
+
* - the ring is degenerate (no segments, or a near-zero perimeter).
|
|
2605
|
+
*/
|
|
2606
|
+
function freezeEchelonAnchor(controlPoints, options) {
|
|
2607
|
+
if (options.echelonAnchor !== void 0) return void 0;
|
|
2608
|
+
if (!resolveEchelon(options.echelon ?? DEFAULT_BATTLE_POSITION_OPTIONS.echelon)) return void 0;
|
|
2609
|
+
const perimeter = buildAreaPerimeter(buildClosedRing(controlPoints, options.smooth ?? DEFAULT_BATTLE_POSITION_OPTIONS.smooth, options.smoothResolution ?? DEFAULT_BATTLE_POSITION_OPTIONS.smoothResolution, DEFAULT_SMOOTH_RESOLUTION$6));
|
|
2610
|
+
if (perimeter.segs.length === 0 || perimeter.totalLength < 1e-6) return void 0;
|
|
2611
|
+
return { echelonAnchor: perimeter.anchorTarget / perimeter.totalLength };
|
|
2612
|
+
}
|
|
2516
2613
|
const BATTLE_POSITION = defineControlMeasure({
|
|
2517
2614
|
metadata: BATTLE_POSITION_METADATA,
|
|
2518
2615
|
generator: createBattlePosition,
|
|
2519
2616
|
defaultOptions: DEFAULT_BATTLE_POSITION_OPTIONS,
|
|
2520
2617
|
rule: area1DrawRule,
|
|
2618
|
+
freezeOrientation: freezeEchelonAnchor,
|
|
2521
2619
|
previewSample: {
|
|
2522
2620
|
controlPoints: [
|
|
2523
2621
|
[-1, -.5],
|
|
@@ -4127,30 +4225,41 @@ const DEFAULT_GENERIC_RECTANGLE_OPTIONS = { filled: false };
|
|
|
4127
4225
|
const GENERIC_RECTANGLE_METADATA = {
|
|
4128
4226
|
id: "rectangle",
|
|
4129
4227
|
name: "Rectangle",
|
|
4130
|
-
description: "A non-doctrinal
|
|
4228
|
+
description: "A non-doctrinal oriented rectangle defined by three adjacent corners.",
|
|
4131
4229
|
entity: "Generic Graphics",
|
|
4132
4230
|
entityType: "Basic Shape",
|
|
4133
4231
|
entitySubtype: "Rectangle",
|
|
4134
4232
|
value: "990103",
|
|
4135
|
-
minCoordinates:
|
|
4136
|
-
maxCoordinates:
|
|
4233
|
+
minCoordinates: 3,
|
|
4234
|
+
maxCoordinates: 3,
|
|
4137
4235
|
geometry: "area",
|
|
4138
4236
|
geometryTypes: ["Polygon"],
|
|
4139
4237
|
drawRule: "Rectangle",
|
|
4140
4238
|
params: FILLED_AREA_PARAMS
|
|
4141
4239
|
};
|
|
4142
4240
|
function createGenericRectangle(coordinates, options = {}) {
|
|
4143
|
-
const
|
|
4144
|
-
|
|
4145
|
-
|
|
4241
|
+
const [c1, c2, c3] = rectangleDrawRule.derive(coordinates);
|
|
4242
|
+
if (!c1 || !c2 || !c3) return {
|
|
4243
|
+
type: "FeatureCollection",
|
|
4244
|
+
features: []
|
|
4245
|
+
};
|
|
4246
|
+
const p1 = project(c1[0], c1[1]);
|
|
4247
|
+
const p2 = project(c2[0], c2[1]);
|
|
4248
|
+
const p3 = project(c3[0], c3[1]);
|
|
4249
|
+
if (Math.hypot(p2[0] - p1[0], p2[1] - p1[1]) < 1e-6) return {
|
|
4250
|
+
type: "FeatureCollection",
|
|
4251
|
+
features: []
|
|
4252
|
+
};
|
|
4253
|
+
const fill = options.filled ?? DEFAULT_GENERIC_RECTANGLE_OPTIONS.filled;
|
|
4254
|
+
if (Math.hypot(p3[0] - p2[0], p3[1] - p2[1]) < 1e-6) return {
|
|
4146
4255
|
type: "FeatureCollection",
|
|
4147
4256
|
features: []
|
|
4148
4257
|
};
|
|
4149
4258
|
const ring = [
|
|
4150
4259
|
p1,
|
|
4151
|
-
[p2[0], p1[1]],
|
|
4152
4260
|
p2,
|
|
4153
|
-
|
|
4261
|
+
p3,
|
|
4262
|
+
[p1[0] + p3[0] - p2[0], p1[1] + p3[1] - p2[1]],
|
|
4154
4263
|
p1
|
|
4155
4264
|
].map((point) => unproject(point[0], point[1]));
|
|
4156
4265
|
return {
|
|
@@ -4159,7 +4268,7 @@ function createGenericRectangle(coordinates, options = {}) {
|
|
|
4159
4268
|
type: "Feature",
|
|
4160
4269
|
properties: {
|
|
4161
4270
|
part: "rectangle",
|
|
4162
|
-
fill
|
|
4271
|
+
fill
|
|
4163
4272
|
},
|
|
4164
4273
|
geometry: {
|
|
4165
4274
|
type: "Polygon",
|
|
@@ -4173,7 +4282,11 @@ const GENERIC_RECTANGLE = defineControlMeasure({
|
|
|
4173
4282
|
generator: createGenericRectangle,
|
|
4174
4283
|
defaultOptions: DEFAULT_GENERIC_RECTANGLE_OPTIONS,
|
|
4175
4284
|
rule: rectangleDrawRule,
|
|
4176
|
-
previewSample: { controlPoints: [
|
|
4285
|
+
previewSample: { controlPoints: [
|
|
4286
|
+
[-.9, -.55],
|
|
4287
|
+
[.9, -.55],
|
|
4288
|
+
[.9, .55]
|
|
4289
|
+
] }
|
|
4177
4290
|
});
|
|
4178
4291
|
//#endregion
|
|
4179
4292
|
//#region src/generators/cm34-mission-tasks/clear.ts
|
|
@@ -6519,11 +6632,11 @@ function buildStrongPointTics(perimeter, gaps, h) {
|
|
|
6519
6632
|
* @param options - {@link StrongPointOptions}.
|
|
6520
6633
|
*/
|
|
6521
6634
|
function createStrongPoint(positions, options = {}) {
|
|
6522
|
-
const { echelon = DEFAULT_STRONG_POINT_OPTIONS.echelon, echelonSize = DEFAULT_STRONG_POINT_OPTIONS.echelonSize, echelonSizePixels, echelonPadding = DEFAULT_STRONG_POINT_OPTIONS.echelonPadding, echelonPosition = DEFAULT_STRONG_POINT_OPTIONS.echelonPosition, metersPerPixel, smooth = DEFAULT_STRONG_POINT_OPTIONS.smooth, smoothResolution = DEFAULT_STRONG_POINT_OPTIONS.smoothResolution } = options;
|
|
6635
|
+
const { echelon = DEFAULT_STRONG_POINT_OPTIONS.echelon, echelonSize = DEFAULT_STRONG_POINT_OPTIONS.echelonSize, echelonSizePixels, echelonPadding = DEFAULT_STRONG_POINT_OPTIONS.echelonPadding, echelonPosition = DEFAULT_STRONG_POINT_OPTIONS.echelonPosition, echelonAnchor, metersPerPixel, smooth = DEFAULT_STRONG_POINT_OPTIONS.smooth, smoothResolution = DEFAULT_STRONG_POINT_OPTIONS.smoothResolution } = options;
|
|
6523
6636
|
const h = resolveEchelonHeight(echelonSize, echelonSizePixels, metersPerPixel);
|
|
6524
6637
|
const verts = buildClosedRing(positions, smooth, smoothResolution, DEFAULT_SMOOTH_RESOLUTION);
|
|
6525
6638
|
const perimeter = buildAreaPerimeter(verts);
|
|
6526
|
-
const { strokes, fills, gaps } = placeEchelon(perimeter, h, echelon, echelonPadding, echelonPosition);
|
|
6639
|
+
const { strokes, fills, gaps } = placeEchelon(perimeter, h, echelon, echelonPadding, echelonPosition, echelonAnchor);
|
|
6527
6640
|
const boundaryCoords = buildGappedLine(verts, gaps);
|
|
6528
6641
|
const tics = buildStrongPointTics(perimeter, gaps, h);
|
|
6529
6642
|
const features = [];
|
|
@@ -6572,6 +6685,7 @@ const STRONG_POINT = defineControlMeasure({
|
|
|
6572
6685
|
generator: createStrongPoint,
|
|
6573
6686
|
defaultOptions: DEFAULT_STRONG_POINT_OPTIONS,
|
|
6574
6687
|
rule: area1DrawRule,
|
|
6688
|
+
freezeOrientation: freezeEchelonAnchor,
|
|
6575
6689
|
previewSample: {
|
|
6576
6690
|
controlPoints: [
|
|
6577
6691
|
[-1, -.5],
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@orbat-mapper/control-measures",
|
|
3
|
-
"version": "0.2.0-alpha.
|
|
3
|
+
"version": "0.2.0-alpha.6",
|
|
4
4
|
"description": "Library for drawing tactical graphics and control measures according to MIL-STD-2525 and APP-6 standards.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Orbat Mapper",
|