Custom Geometry that should depend on starting and ending Point (Wanning Crescent)

Hey,
am having an issue regarding a shape which i want to make in threejs.

https://www.google.com/url?sa=i&url=https%3A%2F%2Fwww.sciencephoto.com%2Fmedia%2F325523%2Fview%2Fwaning-crescent-moon&psig=AOvVaw1v2cLdhKtZp2l18z_XB0no&ust=1713348031004000&source=images&cd=vfe&opi=89978449&ved=0CBIQjRxqFwoTCPCUq_i8xoUDFQAAAAAdAAAAABAE

Here’s the URL, this shape is known as wanning crescent moon shape, this i want to make in threejs but am not able to make it, also i want that it should be dynamic i.e. it should depend and change if i change the starting and ending point.

I tried using Two Bezier curves and then generating points from that and using those points to make a buffergeometry. But that also does’nt worked.
Here are the things that i have tried. Am providing the code template

import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
// Create a scene
const scene = new THREE.Scene();

// Create a camera
const camera = new THREE.PerspectiveCamera(
	75,
	window.innerWidth / window.innerHeight,
	0.1,
	1000,
);
camera.position.set(0, 0, 5);

// Create a renderer
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

const orbitControls = new OrbitControls(camera, renderer.domElement);

// Define control points
const startPoint = new THREE.Vector3(-2, 0, 0);
const endPoint = new THREE.Vector3(2, 0, 0);

const controlPoint1 = new THREE.Vector3(-1, 1, 0); // Control point 1
const controlPoint2 = new THREE.Vector3(1, 1, 0); // Control point 2

const controlPoint3 = new THREE.Vector3(-1, 1.2, 0); // Control point 1
const controlPoint4 = new THREE.Vector3(1, 1.2, 0); //

// Create Bezier curve
const curve1 = new THREE.CubicBezierCurve3(
	startPoint,
	controlPoint1,
	controlPoint2,
	endPoint,
);
const curve2 = new THREE.CubicBezierCurve3(
	startPoint,
	controlPoint3,
	controlPoint4,
	endPoint,
);

const points1 = curve1.getPoints(100);
const points2 = curve2.getPoints(100);

const allPoints = [...points1, ...points2];
const bufferGeom = new THREE.BufferGeometry().setFromPoints(allPoints);
bufferGeom.computeVertexNormals();
bufferGeom.computeBoundingBox();
bufferGeom.computeBoundingSphere();

console.log(bufferGeom);

// Create tube geometry
const tubeGeometry1 = new THREE.TubeGeometry(curve1, 50, 0.2, 20, false);
console.log(tubeGeometry1);
const tubeGeometry2 = new THREE.TubeGeometry(curve2, 50, 0.2, 20, false);

// Create material
const material = new THREE.MeshBasicMaterial({
	color: 0xffff00,
	side: THREE.DoubleSide,
});

// Create the tube mesh
const tubeMesh1 = new THREE.Mesh(bufferGeom, material);
const tubeMesh2 = new THREE.Mesh(tubeGeometry2, material);

// Add tube mesh to the scene
scene.add(tubeMesh1);
scene.add(tubeMesh2);

// Render loop
function animate() {
	requestAnimationFrame(animate);
	orbitControls.update();
	renderer.render(scene, camera);
}
animate();

How can i achieve that ? Thanks in advance

Most likely I do not understand what you want (because I have no idea why you use tubes in the code). Anyway, the shape between two Bezier curves can be created as a mesh in this way:

const shape = new THREE.Shape();
shape.moveTo( startPoint.x, startPoint.y );
shape.bezierCurveTo(
	controlPoint1.x, controlPoint1.y,
	controlPoint2.x, controlPoint2.y,
	endPoint.x, endPoint.y
);
shape.bezierCurveTo(
	controlPoint4.x, controlPoint4.y,
	controlPoint3.x, controlPoint3.y,
	startPoint.x, startPoint.y,
);

const geometry = new THREE.ShapeGeometry( shape );
const material = new THREE.MeshBasicMaterial( { color: 'linen' } );
const mesh = new THREE.Mesh( geometry, material ) ;
scene.add( mesh );

And the result is:

image

Also this.

4 Likes

Thanks, Worked Out Perfectly

1 Like