I tried to animate with Three.js to show the intersection plane on a 3d object which this following code:
import React, { useRef, useEffect, useState } from 'react';
import * as THREE from 'three';
export const App = () => {
const mountRef = useRef(null);
const [planeAngle, setPlaneAngle] = useState(Math.PI / 4); // Initial angle in radians
useEffect(() => {
const width = 800;
const height = 600;
// Scene setup
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x000000);
const camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 1000);
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(width, height);
mountRef.current.appendChild(renderer.domElement);
// Cone
const length = 2;
const coneHeight = length * Math.SQRT2;
const coneRadius = length / Math.SQRT2;
const coneGeometry = new THREE.ConeGeometry(coneRadius, coneHeight, 32);
const coneMaterial = new THREE.MeshBasicMaterial({ color: 0x00ff00, wireframe: true });
const cone = new THREE.Mesh(coneGeometry, coneMaterial);
cone.position.y = 0;
scene.add(cone);
// Plane
const planeSize = length * Math.SQRT2;
const planeGeometry = new THREE.PlaneGeometry(planeSize, planeSize);
const planeMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000, side: THREE.DoubleSide, transparent: true, opacity: 0.5 });
const plane = new THREE.Mesh(planeGeometry, planeMaterial);
scene.add(plane);
// Position camera
camera.position.set(3, 3, 5);
camera.lookAt(0, 0, 0);
// Animation
const animate = () => {
requestAnimationFrame(animate);
// Set plane rotation based on planeAngle
plane.rotation.set(planeAngle, 0, 0);
// Keep plane centered
plane.position.set(0, 0, 0);
renderer.render(scene, camera);
};
animate();
// Cleanup
return () => {
mountRef.current.removeChild(renderer.domElement);
};
}, [planeAngle]);
const handleAngleChange = (event) => {
setPlaneAngle(parseFloat(event.target.value));
};
return (
<div>
<div ref={mountRef}></div>
<div style={{ position: 'absolute', bottom: '10px', left: '10px', color: 'white' }}>
Plane Angle:
<input
type="range"
min="0"
max={Math.PI / 2}
step="0.01"
value={planeAngle}
onChange={handleAngleChange}
style={{ width: '200px' }}
/>
{(planeAngle * 180 / Math.PI).toFixed(2)}°
</div>
</div>
);
};
produced the following rendering:
However, this is not exactly what I was looking for, because I was looking to produce a rendering like this:
So I had tried a lot of approaches in making only the intersected plane within the 3d object to show and hide the parts of the plane outside of the 3d object, but many of them seemed to be too convoluted. Is there a simple and intuitive way to get the desired rendering without too much tinkering?