forked from neon-ninja/pythagoras
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.js
More file actions
154 lines (121 loc) · 5.21 KB
/
main.js
File metadata and controls
154 lines (121 loc) · 5.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
// Scene setup
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// Lighting
const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
scene.add(ambientLight);
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);
directionalLight.position.set(5, 10, 7.5);
scene.add(directionalLight);
// Controls
const controls = new OrbitControls(camera, renderer.domElement);
// Pythagorean triple (a=3, b=4, c=5)
const a = 3;
const b = 4;
const c = 5;
// Create the triangle and squares
const group = new THREE.Group();
// Triangle
const triangleShape = new THREE.Shape();
triangleShape.moveTo(0, 0);
triangleShape.lineTo(a, 0);
triangleShape.lineTo(0, b);
triangleShape.lineTo(0, 0);
const triangleGeometry = new THREE.ShapeGeometry(triangleShape);
const triangleMaterial = new THREE.MeshStandardMaterial({ color: 0xcccccc, side: THREE.DoubleSide });
const triangleMesh = new THREE.Mesh(triangleGeometry, triangleMaterial);
group.add(triangleMesh);
// Square on side A
const squareA_Geometry = new THREE.PlaneGeometry(a, a);
const squareA_Material = new THREE.MeshStandardMaterial({ color: 0xff0000, side: THREE.DoubleSide });
const squareA = new THREE.Mesh(squareA_Geometry, squareA_Material);
squareA.position.set(a / 2, -a / 2, 0);
group.add(squareA);
// Square on side B
const squareB_Geometry = new THREE.PlaneGeometry(b, b);
const squareB_Material = new THREE.MeshStandardMaterial({ color: 0x00ff00, side: THREE.DoubleSide });
const squareB = new THREE.Mesh(squareB_Geometry, squareB_Material);
squareB.position.set(-b / 2, b / 2, 0);
group.add(squareB);
// Square on side C (hypotenuse)
const squareC_Geometry = new THREE.PlaneGeometry(c, c);
const squareC_Material = new THREE.MeshStandardMaterial({ color: 0x0000ff, side: THREE.DoubleSide });
const squareC = new THREE.Mesh(squareC_Geometry, squareC_Material);
const angle = Math.atan2(b, -a);
squareC.position.set(a / 2, b / 2, 0);
squareC.rotation.z = angle;
squareC.position.x += (c/2) * Math.sin(angle);
squareC.position.y -= (c/2) * Math.cos(angle);
group.add(squareC);
scene.add(group);
// Center the group
const box = new THREE.Box3().setFromObject(group);
const center = box.getCenter(new THREE.Vector3());
group.position.sub(center);
camera.position.z = 15;
// Water simulation (placeholder)
const waterMaterial = new THREE.MeshStandardMaterial({ color: 0x00ffff, transparent: true, opacity: 0.7 });
// Water in square C
const waterC_Geometry = new THREE.PlaneGeometry(c, c);
const waterC = new THREE.Mesh(waterC_Geometry, waterMaterial);
waterC.position.copy(squareC.position);
waterC.rotation.copy(squareC.rotation);
waterC.position.z += 0.1; // Slightly in front
group.add(waterC);
// Water in square A
const waterA_Geometry = new THREE.PlaneGeometry(a, 0); // Initially empty
const waterA = new THREE.Mesh(waterA_Geometry, waterMaterial);
waterA.position.copy(squareA.position);
waterA.rotation.copy(squareA.rotation);
waterA.position.z += 0.1;
group.add(waterA);
// Water in square B
const waterB_Geometry = new THREE.PlaneGeometry(b, 0); // Initially empty
const waterB = new THREE.Mesh(waterB_Geometry, waterMaterial);
waterB.position.copy(squareB.position);
waterB.rotation.copy(squareB.rotation);
waterB.position.z += 0.1;
group.add(waterB);
function animate() {
requestAnimationFrame(animate);
// Simple rotation for demonstration
group.rotation.z += 0.005;
// Placeholder for fluid logic
const rotationZ = group.rotation.z % (2 * Math.PI);
// This is a very simplified simulation.
// It calculates the "fill" based on the rotation angle.
let fillRatio = 0;
if (rotationZ > Math.PI / 4 && rotationZ < 3 * Math.PI / 4) {
fillRatio = (rotationZ - Math.PI / 4) / (Math.PI / 2);
} else if (rotationZ > 5 * Math.PI / 4 && rotationZ < 7 * Math.PI / 4) {
fillRatio = 1 - ((rotationZ - 5 * Math.PI / 4) / (Math.PI / 2));
}
fillRatio = Math.max(0, Math.min(1, fillRatio));
// Update water levels
const waterCHeight = c * (1 - fillRatio);
waterC.geometry.dispose();
waterC.geometry = new THREE.PlaneGeometry(c, waterCHeight);
waterC.position.y = squareC.position.y - (c - waterCHeight) / 2 * Math.cos(squareC.rotation.z);
waterC.position.x = squareC.position.x + (c - waterCHeight) / 2 * Math.sin(squareC.rotation.z);
const waterAHeight = a * fillRatio;
waterA.geometry.dispose();
waterA.geometry = new THREE.PlaneGeometry(a, waterAHeight);
waterA.position.y = squareA.position.y - (a - waterAHeight) / 2;
const waterBHeight = b * fillRatio;
waterB.geometry.dispose();
waterB.geometry = new THREE.PlaneGeometry(b, waterBHeight);
waterB.position.x = squareB.position.x - (b - waterBHeight) / 2;
controls.update();
renderer.render(scene, camera);
}
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
animate();