From 7f2c43ea23f0f0a2bf0ce336b22d5b2246724792 Mon Sep 17 00:00:00 2001 From: Florian Kinder Date: Tue, 3 Feb 2026 12:11:16 +0100 Subject: [PATCH 1/2] fix: correct ELLIPSE marker size to match in-game display ELLIPSE markers were rendered larger than in-game due to incorrect size calculation using an arbitrary 0.015 constant. Changes: - Calculate ellipse perimeter points in Arma coordinates (meters) - Convert points to latLng using existing armaToLatLng function - Render as L.polygon instead of L.circle for proper ellipse support - Use both size[0] (X radius) and size[1] (Y radius) for true ellipses - Apply rotation using existing _rotatePoints method This aligns ELLIPSE rendering with RECTANGLE, which already correctly converts Arma coordinates to map coordinates. --- static/scripts/ocap.marker.js | 65 ++++++++++++++++++++++++++++------- 1 file changed, 53 insertions(+), 12 deletions(-) diff --git a/static/scripts/ocap.marker.js b/static/scripts/ocap.marker.js index f9aec03d..abde89ea 100644 --- a/static/scripts/ocap.marker.js +++ b/static/scripts/ocap.marker.js @@ -287,9 +287,22 @@ class Marker { if (alpha === undefined || alpha === null) { alpha = 1 } this._createMarker(latLng, dir, alpha); } else if (this._shape === "ELLIPSE") { - latLng = armaToLatLng(pos); + let centerX = pos[0]; + let centerY = pos[1]; + let radiusX = this._size[0]; // Arma markerSize is radius in meters + let radiusY = this._size[1]; + + // Calculate ellipse perimeter points in Arma coordinates + let pointsRaw = this._calculateEllipsePoints(centerX, centerY, radiusX, radiusY); + points = pointsRaw.map(coord => { + return armaToLatLng(coord); + }); + + // Apply rotation around center + let pointsRotate = this._rotatePoints(armaToLatLng(pos), points, dir); + if (alpha === undefined || alpha === null) { alpha = 0.2 } - this._createMarker(latLng, dir, alpha); + this._createMarker(pointsRotate, dir, alpha); } else if (this._shape === "RECTANGLE") { let startX = pos[0]; let startY = pos[1]; @@ -336,17 +349,31 @@ class Marker { this._marker.setLatLng(latLng); } else if (this._shape === "ELLIPSE") { latLng = armaToLatLng(pos); + let centerX = pos[0]; + let centerY = pos[1]; + let radiusX = this._size[0]; + let radiusY = this._size[1]; if (alpha === undefined || alpha === null) { alpha = 0.3 } + // Calculate ellipse perimeter points in Arma coordinates + let pointsRaw = this._calculateEllipsePoints(centerX, centerY, radiusX, radiusY); + points = pointsRaw.map(coord => { + return armaToLatLng(coord); + }); + // check if update is needed let variance = 0; - let curMarkerCenter = this._marker._latlng; - variance = variance + Math.abs((Math.abs(curMarkerCenter.lat) - Math.abs(latLng.lat))); - variance = variance + Math.abs((Math.abs(curMarkerCenter.lng) - Math.abs(latLng.lng))); + try { + let curMarkerCenter = this._marker.getCenter(); + variance = variance + Math.abs((Math.abs(curMarkerCenter.lat) - Math.abs(latLng.lat))); + variance = variance + Math.abs((Math.abs(curMarkerCenter.lng) - Math.abs(latLng.lng))); - // if (variance > 5) { - this._marker.setLatLng(latLng).redraw(); - // }; + // Apply rotation around center + let pointsRotate = this._rotatePoints(armaToLatLng(pos), points, dir); + this._marker.setLatLngs(pointsRotate).redraw(); + } catch { + // If the layer is hidden, this will error because _marker.getCenter() will fail + } } else if (this._shape === "RECTANGLE") { latLng = armaToLatLng(pos); let startX = pos[0]; @@ -409,6 +436,21 @@ class Marker { return res } + // Calculate ellipse perimeter points in Arma coordinates + // cx, cy: center position in Arma meters + // rx, ry: radii in Arma meters (from markerSize) + // Returns array of [x, y] points in Arma coordinates + _calculateEllipsePoints (cx, cy, rx, ry, numPoints = 36) { + const points = []; + for (let i = 0; i < numPoints; i++) { + const angle = (i / numPoints) * 2 * Math.PI; + const x = cx + rx * Math.cos(angle); + const y = cy + ry * Math.sin(angle); + points.push([x, y]); + } + return points; + } + isMagIcon () { if ( // projectiles @@ -523,14 +565,13 @@ class Marker { } if (this._shape === "ELLIPSE") { - let rad = this._size[0] * 0.015 * window.multiplier; - + // latLng now contains polygon points (calculated in _updateAtFrame) if (this._brushPattern) { this._brushPattern.addTo(map); - marker = L.circle(latLng, { radius: rad, noClip: false, interactive: false, fillPattern: this._brushPattern }); + marker = L.polygon(latLng, { noClip: false, interactive: false, fillPattern: this._brushPattern }); L.Util.setOptions(marker, this._shapeOptions); } else { - marker = L.circle(latLng, { radius: rad, noClip: false, interactive: false }); + marker = L.polygon(latLng, { noClip: false, interactive: false }); L.Util.setOptions(marker, this._shapeOptions); } marker.addTo(systemMarkersLayerGroup); From 53460eafd51047149b81f772d3eda1ceca5657b6 Mon Sep 17 00:00:00 2001 From: Florian Kinder Date: Tue, 3 Feb 2026 12:34:32 +0100 Subject: [PATCH 2/2] fix: add ELLIPSE to updateRender and defensive size checks - Include ELLIPSE shape in updateRender method (was only RECTANGLE) - Add defensive checks for this._size array access to prevent silent errors when size data is malformed --- static/scripts/ocap.marker.js | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/static/scripts/ocap.marker.js b/static/scripts/ocap.marker.js index abde89ea..62c85266 100644 --- a/static/scripts/ocap.marker.js +++ b/static/scripts/ocap.marker.js @@ -239,7 +239,7 @@ class Marker { } updateRender (f) { - if (this._shape === "RECTANGLE") { + if (this._shape === "RECTANGLE" || this._shape === "ELLIPSE") { const frameIndex = this._markerOnFrame(f); if (frameIndex >= 0 && (this._side === ui.currentSide || this._side === "GLOBAL")) { this._updateAtFrame(frameIndex); @@ -289,8 +289,9 @@ class Marker { } else if (this._shape === "ELLIPSE") { let centerX = pos[0]; let centerY = pos[1]; - let radiusX = this._size[0]; // Arma markerSize is radius in meters - let radiusY = this._size[1]; + // Ensure size is valid array, fallback to [100, 100] if not + let radiusX = (Array.isArray(this._size) && this._size[0]) ? this._size[0] : 100; + let radiusY = (Array.isArray(this._size) && this._size[1]) ? this._size[1] : 100; // Calculate ellipse perimeter points in Arma coordinates let pointsRaw = this._calculateEllipsePoints(centerX, centerY, radiusX, radiusY); @@ -351,8 +352,9 @@ class Marker { latLng = armaToLatLng(pos); let centerX = pos[0]; let centerY = pos[1]; - let radiusX = this._size[0]; - let radiusY = this._size[1]; + // Ensure size is valid array, fallback to [100, 100] if not + let radiusX = (Array.isArray(this._size) && this._size[0]) ? this._size[0] : 100; + let radiusY = (Array.isArray(this._size) && this._size[1]) ? this._size[1] : 100; if (alpha === undefined || alpha === null) { alpha = 0.3 } // Calculate ellipse perimeter points in Arma coordinates