import React, { useEffect, useRef, useState } from 'react'; import * as THREE from 'three'; const CarbonStructures3D = () => { const diamondRef = useRef(null); const graphiteRef = useRef(null); const [activeStructure, setActiveStructure] = useState('diamond'); useEffect(() => { const currentRef = activeStructure === 'diamond' ? diamondRef : graphiteRef; if (!currentRef.current) return; // Scene setup const scene = new THREE.Scene(); scene.background = new THREE.Color(0x1a1a2e); const camera = new THREE.PerspectiveCamera( 75, currentRef.current.clientWidth / currentRef.current.clientHeight, 0.1, 1000 ); camera.position.z = 12; const renderer = new THREE.WebGLRenderer({ antialias: true }); renderer.setSize(currentRef.current.clientWidth, currentRef.current.clientHeight); currentRef.current.appendChild(renderer.domElement); // Lighting const ambientLight = new THREE.AmbientLight(0xffffff, 0.6); scene.add(ambientLight); const pointLight1 = new THREE.PointLight(0xffffff, 0.8); pointLight1.position.set(10, 10, 10); scene.add(pointLight1); const pointLight2 = new THREE.PointLight(0x4488ff, 0.4); pointLight2.position.set(-10, -10, -10); scene.add(pointLight2); // Materials const carbonMaterial = new THREE.MeshPhongMaterial({ color: 0x333333, shininess: 100, specular: 0x555555 }); const bondMaterial = new THREE.MeshPhongMaterial({ color: 0x666666, shininess: 50 }); const group = new THREE.Group(); if (activeStructure === 'diamond') { // Diamond structure - tetrahedral arrangement const atomGeometry = new THREE.SphereGeometry(0.4, 32, 32); const bondGeometry = new THREE.CylinderGeometry(0.08, 0.08, 1, 8); // Create diamond cubic structure const positions = [ [0, 0, 0], [2, 2, 0], [2, 0, 2], [0, 2, 2], [1, 1, 1], [3, 3, 1], [3, 1, 3], [1, 3, 3], [4, 0, 0], [4, 2, 2], [2, 4, 0], [0, 4, 2], [2, 2, 4], [0, 0, 4], [4, 4, 0], [4, 0, 4], [0, 4, 4], [4, 4, 4] ]; // Center the structure positions.forEach(pos => { pos[0] -= 2; pos[1] -= 2; pos[2] -= 2; }); // Add atoms positions.forEach(pos => { const atom = new THREE.Mesh(atomGeometry, carbonMaterial); atom.position.set(pos[0], pos[1], pos[2]); group.add(atom); }); // Add bonds const bonds = [ [0, 4], [1, 4], [2, 4], [3, 4], [1, 5], [8, 5], [10, 5], [2, 6], [8, 6], [9, 6], [3, 7], [10, 7], [11, 7], [8, 14], [9, 15], [10, 14], [11, 16], [12, 13], [12, 15], [12, 16], [13, 16] ]; bonds.forEach(bond => { const start = new THREE.Vector3(...positions[bond[0]]); const end = new THREE.Vector3(...positions[bond[1]]); const direction = new THREE.Vector3().subVectors(end, start); const length = direction.length(); const bondMesh = new THREE.Mesh(bondGeometry, bondMaterial); bondMesh.scale.y = length; bondMesh.position.copy(start).add(direction.multiplyScalar(0.5)); bondMesh.quaternion.setFromUnitVectors( new THREE.Vector3(0, 1, 0), direction.normalize() ); group.add(bondMesh); }); } else { // Graphite structure - layered hexagonal sheets const atomGeometry = new THREE.SphereGeometry(0.3, 32, 32); const bondGeometry = new THREE.CylinderGeometry(0.08, 0.08, 1, 8); // Create three layers for (let layer = 0; layer < 3; layer++) { const yOffset = layer * 3.5; const xOffset = layer % 2 === 0 ? 0 : 0.866; // Hexagonal pattern for each layer for (let row = 0; row < 3; row++) { for (let col = 0; col < 4; col++) { const x = col * 1.732 + xOffset - 2.5; const z = row * 1.5 - 1.5; const y = yOffset - 3; // Add atom const atom = new THREE.Mesh(atomGeometry, carbonMaterial); atom.position.set(x, y, z); atom.userData = { layer, row, col }; group.add(atom); // Add bonds within the layer if (col < 3) { const bond = new THREE.Mesh(bondGeometry, bondMaterial); bond.position.set(x + 0.866, y, z); bond.rotation.z = Math.PI / 2; bond.scale.y = 1.732; group.add(bond); } if (row < 2 && (col % 2 === (row % 2 === 0 ? 0 : 1))) { const bond = new THREE.Mesh(bondGeometry, bondMaterial); bond.position.set(x + 0.433, y, z + 0.75); bond.rotation.x = Math.PI / 2; bond.rotation.z = Math.PI / 6; bond.scale.y = 1.5; group.add(bond); } } } } } scene.add(group); // Animation let mouseX = 0; let mouseY = 0; let targetRotationX = 0; let targetRotationY = 0; const onMouseMove = (event) => { mouseX = (event.clientX / window.innerWidth) * 2 - 1; mouseY = -(event.clientY / window.innerHeight) * 2 + 1; }; window.addEventListener('mousemove', onMouseMove); const animate = () => { requestAnimationFrame(animate); targetRotationY = mouseX * 0.5; targetRotationX = mouseY * 0.5; group.rotation.y += (targetRotationY - group.rotation.y) * 0.05; group.rotation.x += (targetRotationX - group.rotation.x) * 0.05; group.rotation.y += 0.005; renderer.render(scene, camera); }; animate(); // Cleanup return () => { window.removeEventListener('mousemove', onMouseMove); currentRef.current?.removeChild(renderer.domElement); renderer.dispose(); }; }, [activeStructure]); return (
Interactive 3D visualization of diamond and graphite
Diamond has a tetrahedral crystal structure where each carbon atom is covalently bonded to four other carbon atoms in a 3D network. This strong bonding makes diamond extremely hard and gives it a high melting point.
Graphite consists of layered hexagonal sheets of carbon atoms. Within each layer, atoms are strongly bonded, but layers are held together by weak van der Waals forces, making graphite soft and slippery.