added function for find area
This commit is contained in:
parent
2e19637173
commit
19e5b9f311
|
@ -0,0 +1,17 @@
|
||||||
|
import { Vector2 } from "three";
|
||||||
|
|
||||||
|
export function computeAreaFrom3DPoints(points3D: any) {
|
||||||
|
// Project 3D points onto XZ plane
|
||||||
|
const projected = points3D.map((p: any) => new Vector2(p[0], p[2]));
|
||||||
|
|
||||||
|
// Shoelace formula for 2D polygon
|
||||||
|
let area = 0;
|
||||||
|
const n = projected.length;
|
||||||
|
for (let i = 0; i < n - 1; i++) {
|
||||||
|
const curr = projected[i];
|
||||||
|
const next = projected[i + 1];
|
||||||
|
area += curr.x * next.y - next.x * curr.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Math.abs(area) / 2;
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
import React, { useState, useEffect, useMemo, useRef } from "react";
|
import React, { useState, useEffect, useMemo, useRef } from "react";
|
||||||
import { Line, Sphere } from "@react-three/drei";
|
import { Html, Line, Sphere } from "@react-three/drei";
|
||||||
import { useThree, useFrame } from "@react-three/fiber";
|
import { useThree, useFrame } from "@react-three/fiber";
|
||||||
import * as THREE from "three";
|
import * as THREE from "three";
|
||||||
import {
|
import {
|
||||||
|
@ -17,6 +17,8 @@ import {
|
||||||
import { getZonesApi } from "../../../services/factoryBuilder/zones/getZonesApi";
|
import { getZonesApi } from "../../../services/factoryBuilder/zones/getZonesApi";
|
||||||
|
|
||||||
import * as CONSTANTS from "../../../types/world/worldConstants";
|
import * as CONSTANTS from "../../../types/world/worldConstants";
|
||||||
|
import * as turf from '@turf/turf';
|
||||||
|
import { computeAreaFrom3DPoints } from "../functions/computeAreaFrom3DPoints";
|
||||||
|
|
||||||
const ZoneGroup: React.FC = () => {
|
const ZoneGroup: React.FC = () => {
|
||||||
const { camera, pointer, gl, raycaster, scene, controls } = useThree();
|
const { camera, pointer, gl, raycaster, scene, controls } = useThree();
|
||||||
|
@ -526,11 +528,12 @@ const ZoneGroup: React.FC = () => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<group ref={groupsRef} name="zoneGroup">
|
<group ref={groupsRef} name="zoneGroup">
|
||||||
<group name="zones" visible={!toggleView}>
|
<group name="zones" visible={!toggleView}>
|
||||||
{zones.map((zone: any) => (
|
{zones.map((zone: any, index: number) => (
|
||||||
<group key={zone.zoneId} name={zone.zoneName} visible={false}>
|
<group key={`${zone.zoneId}-${index}`} name={zone.zoneName} visible={false}>
|
||||||
{zone.points
|
{zone.points
|
||||||
.slice(0, -1)
|
.slice(0, -1)
|
||||||
.map((point: [number, number, number], index: number) => {
|
.map((point: [number, number, number], index: number) => {
|
||||||
|
@ -549,7 +552,7 @@ const ZoneGroup: React.FC = () => {
|
||||||
const midpoint = new THREE.Vector3(
|
const midpoint = new THREE.Vector3(
|
||||||
(point1.x + point2.x) / 2,
|
(point1.x + point2.x) / 2,
|
||||||
CONSTANTS.zoneConfig.height / 2 +
|
CONSTANTS.zoneConfig.height / 2 +
|
||||||
(zone.layer - 1) * CONSTANTS.zoneConfig.height,
|
(zone.layer - 1) * CONSTANTS.zoneConfig.height,
|
||||||
(point1.z + point2.z) / 2
|
(point1.z + point2.z) / 2
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -592,7 +595,60 @@ const ZoneGroup: React.FC = () => {
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
|
|
||||||
</group>
|
</group>
|
||||||
|
<group name="zoneArea">
|
||||||
|
{zones.map((zone: any, index: any) => {
|
||||||
|
const points3D = zone.points;
|
||||||
|
const coords2D = points3D.map((p: any) => [p[0], p[2]]);
|
||||||
|
|
||||||
|
if (
|
||||||
|
coords2D.length < 3 ||
|
||||||
|
coords2D[0][0] !== coords2D[coords2D.length - 1][0] ||
|
||||||
|
coords2D[0][1] !== coords2D[coords2D.length - 1][1]
|
||||||
|
) {
|
||||||
|
coords2D.push(coords2D[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
const polygon = turf.polygon([coords2D]);
|
||||||
|
const center2D = turf.center(polygon).geometry.coordinates;
|
||||||
|
|
||||||
|
const sumY = points3D.reduce((sum: number, p: any) => sum + p[1], 0);
|
||||||
|
const avgY = sumY / points3D.length;
|
||||||
|
|
||||||
|
const area = computeAreaFrom3DPoints(points3D);
|
||||||
|
const formattedArea = `${area.toFixed(2)} m²`;
|
||||||
|
|
||||||
|
const htmlPosition: [number, number, number] = [
|
||||||
|
center2D[0],
|
||||||
|
avgY + CONSTANTS.zoneConfig.height,
|
||||||
|
center2D[1]
|
||||||
|
];
|
||||||
|
return (
|
||||||
|
<Html
|
||||||
|
// data
|
||||||
|
key={`${index}-${zone}`}
|
||||||
|
position={htmlPosition}
|
||||||
|
// class
|
||||||
|
wrapperClass="distance-text-wrapper"
|
||||||
|
className="distance-text"
|
||||||
|
// other
|
||||||
|
zIndexRange={[1, 0]}
|
||||||
|
prepend
|
||||||
|
center
|
||||||
|
sprite
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className={`distance area line-${zone}`}
|
||||||
|
key={`${index}-${zone}`}
|
||||||
|
>
|
||||||
|
{zone.zoneName} ({formattedArea})
|
||||||
|
</div>
|
||||||
|
</Html>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</group>
|
||||||
|
|
||||||
<group name="zonePoints" visible={toggleView}>
|
<group name="zonePoints" visible={toggleView}>
|
||||||
{zones
|
{zones
|
||||||
.filter((zone: any) => zone.layer === activeLayer)
|
.filter((zone: any) => zone.layer === activeLayer)
|
||||||
|
@ -624,6 +680,7 @@ const ZoneGroup: React.FC = () => {
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</group>
|
</group>
|
||||||
|
|
||||||
</group>
|
</group>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -19,6 +19,9 @@
|
||||||
border-radius: #{$border-radius-medium};
|
border-radius: #{$border-radius-medium};
|
||||||
box-shadow: var(--box-shadow-light);
|
box-shadow: var(--box-shadow-light);
|
||||||
}
|
}
|
||||||
|
.area{
|
||||||
|
background: #008cff;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.pointer-none {
|
.pointer-none {
|
||||||
|
|
Loading…
Reference in New Issue