Arrows, Circle finished

This commit is contained in:
Tomas Richtar
2025-05-28 17:45:01 +02:00
parent 2f18d2f06f
commit 3edc2570be
5 changed files with 418 additions and 546 deletions

View File

@@ -1,9 +1,11 @@
const distancePerDegreeLongitude = 111.320; // 2π×6378.1km/360
const distancePerDegreeLatitude = 110.574; // 2π×6356.75km/360
import * as turf from "@turf/turf";
import { toMercator, toWgs84 } from '@turf/projection';
//CIRCLE
const distancePerDegreeLongitude = 111.320; // 2π×6378.1km/360
const distancePerDegreeLatitude = 110.574; // 2π×6356.75km/360
//GEOJSON
/**
* @param {Object} center - The center point of the circle.
* @param {number} center.x
@@ -11,7 +13,7 @@ import { toMercator, toWgs84 } from '@turf/projection';
* @param {number} radius - The radius of the circle.
* @param {number} density - The number of points used to approximate the circle.
*
* @returns {Object} GeoJSON Feature representing the circle polygon.
* @returns {GeoJSON.Feature<GeoJSON.Polygon>} GeoJSON Feature representing the circle polygon.
*/
export function getCirclePolygon(center, radius, density = 64) {
const points = [];
@@ -34,38 +36,58 @@ export function getCirclePolygon(center, radius, density = 64) {
// Close the circle by adding the first point again
points.push(points[0]);
return turf.polygon([[...points]]);
return {
type: "Feature",
geometry: {
type: "Polygon",
coordinates: [points]
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [points]
},
properties: {}
"properties": {}
};
}
function getDistancePerDegreeLongitude(latitude) {
return 111.320 * Math.cos(latitude * Math.PI / 180);
//GEOJSON
//CANVAS
/**
* @param {Object} center - The center point of the circle.
* @param {number} center.x
* @param {number} center.y
* @param {number} radius - The radius of the circle.
* @param {number} density - The number of points used to approximate the circle.
*
* @returns {{x: number, y: number}[]} An array of points representing the vertices of the circle polygon.
*/
export function getCirclePolygonEuclidean(center, radius, density) {
const points = [];
for (let i = 0; i < density; i++) {
const angle = (i / density) * Math.PI * 2;
const x = center.x + radius * Math.cos(angle);
const y = center.y + radius * Math.sin(angle);
points.push({ x, y });
}
return points;
}
//CANVAS
//CIRCLE
//RECTANGLE
//GEOJSON
/**
* @param {Object} center - The center point of the rectangle.
* @param {number} center.x
* @param {number} center.y
* @param {number} sideA - The length of the first side of the rectangle.
* @param {number} sideB - The length of the second side of the rectangle.
* @param {number} width - The length of the first side of the rectangle.
* @param {number} height - The length of the second side of the rectangle.
* @param {number} rotation - The angle (in radians) by which to rotate the rectangle.
*
* @returns {Object} GeoJSON Feature representing the rectangle polygon.
* @returns {GeoJSON.Feature<GeoJSON.Polygon>} GeoJSON Feature representing the rectangle polygon.
*/
export function getRectanglePolygon(center, width, height, rotation = 0) {
const widthMeters = width * 1000 ;
const heightMeters = height * 1000;
// 1. Střed převedeme do metrického systému (Web Mercator)
const centerMerc = toMercator(turf.point(center)).geometry.coordinates;
// 2. Vypočítáme rohy čtverce v metrech
const halfWidth = widthMeters / 2;
const halfHeight = heightMeters / 2;
@@ -76,13 +98,11 @@ export function getRectanglePolygon(center, width, height, rotation = 0) {
[centerMerc[0] - halfWidth, centerMerc[1] - halfHeight], // bottomLeft
];
// 3. Otočení (volitelně)
if (rotation !== 0) {
const rad = (rotation * Math.PI) / 180;
corners = corners.map(([x, y]) => rotateXY(x, y, centerMerc[0], centerMerc[1], rad));
}
// 4. Uzavřeme polygon a převedeme zpět do WGS84
corners.push(corners[0]);
const wgsCoords = corners.map(([x, y]) => toWgs84([x, y]));
@@ -98,40 +118,35 @@ function rotateXY(x, y, cx, cy, angleRad) {
const ry = cy + dx * sin + dy * cos;
return [rx, ry];
}
/*
const [lon, lat] = center;
// Přepočet metrů na stupně:
const degLat = height / distancePerDegreeLatitude / 2;
const degLon = width / (distancePerDegreeLongitude * Math.cos(lat * Math.PI / 180)) / 2;
// Rohy bez rotace (v relative souřadnicích)
//GEOJSON
//CANVAS
/**
* @param {Object} center - The center point of the rectangle.
* @param {number} center.x
* @param {number} center.y
* @param {number} sideA - The length of the first side of the rectangle.
* @param {number} sideB - The length of the second side of the rectangle.
* @param {number} rotation - The angle (in radians) by which to rotate the rectangle.
*
* @returns {{x: number, y: number}[]} An array of points representing the vertices of the rectangle polygon.
*/
export function getRectanglePolygonEuclidean(center, sideA, sideB, rotation) {
const halfA = sideA / 2;
const halfB = sideB / 2;
const corners = [
[-degLon, -degLat],
[ degLon, -degLat],
[ degLon, degLat],
[-degLon, degLat]
{ x: -halfA, y: -halfB },
{ x: halfA, y: -halfB },
{ x: halfA, y: halfB },
{ x: -halfA, y: halfB }
];
// Rotace a posun
const rotated = corners.map(([dx, dy]) => {
const x = dx;
const y = dy;
const rotatedX = x * Math.cos(rotation) - y * Math.sin(rotation);
const rotatedY = x * Math.sin(rotation) + y * Math.cos(rotation);
return [lon + rotatedX, lat + rotatedY];
return corners.map(point => {
return {
x: center.x + point.x * Math.cos(rotation) - point.y * Math.sin(rotation),
y: center.y + point.x * Math.sin(rotation) + point.y * Math.cos(rotation)
};
});
// Uzavření polygonu
rotated.push(rotated[0]);
return {
type: "Feature",
geometry: {
type: "Polygon",
coordinates: [rotated]
},
properties: {}
};*/
}
//CAVNAS
//RECTANGLE