I am currently struggling to create shapes in three.js dynamically from the point cloud. Hence I am using ConvexGeometry, it works perfectly fine for convex shapes and it is getting difficult when I need a concave shape.
I am drawing a line on the 2D plane (red line from screenshot) then I take all points from the line or curve, clone them, and rotate around the x axis. And now when I have a point cloud, I wish I could simply make a shape. Here are the results: rendering shapes As you can see 2nd and 3rd segments look good but for the first one mesh isn't covering points as I need. rendering concave shape I need any suggestions or ideas on how to achieve the desired results.
Here is my component rendering a shape:
import { Vector3 } from "three";
import { ConvexGeometry } from "three/examples/jsm/Addons.js";
type PointsToGeometryProps = {
pointsData: number[][];
};
export function PointsToGeometry({ pointsData }: PointsToGeometryProps) {
const axis = new Vector3(1, 0, 0);
const basePoints = pointsData.map((p) => new Vector3(p[0], p[1], p[2]));
const rotations = 100;
const points = [...basePoints];
for (let i = 1; i <= rotations; i++) {
const angle = (i * 2 * Math.PI) / rotations;
const rotatedPoints = basePoints
.map((p) => {
if (!p.y) return;
return p.clone().applyAxisAngle(axis, angle);
})
.filter((p) => p);
points.push(...(rotatedPoints as Vector3[]));
}
const geometry = new ConvexGeometry(points);
return (
<mesh geometry={geometry}>
<meshStandardMaterial />
</mesh>
);
}
Thanks in advance
I wanted to share the solution I found for my problem. It turns out that the LatheGeometry class from the Three.js library is exactly what I needed. I can't believe I overlooked it for so long. If anyone else encounters a similar issue, I highly recommend using LatheGeometry. Here’s the updated code snippet that worked for me:
import { LatheGeometry, Vector2 } from "three";
type PointsToGeometryProps = {
pointsData: Vector2[];
};
export function PointsToGeometry({ pointsData }: PointsToGeometryProps) {
const rotations = 100;
const rotatedPoints = pointsData.map((p) =>
p.rotateAround(new Vector2(0, 0), Math.PI / 2)
);
const geometry = new LatheGeometry(rotatedPoints, rotations).rotateZ(
-Math.PI / 2
);
return (
<mesh geometry={geometry}>
<meshStandardMaterial />
</mesh>
);
}
I hope this helps someone else!