|
@@ -1,21 +1,21 @@
|
1
|
1
|
import * as THREE from "three";
|
2
|
2
|
|
3
|
|
-var OrbitControls = require("three-orbit-controls")(THREE);
|
|
3
|
+const OrbitControls = require("three-orbit-controls")(THREE);
|
4
|
4
|
|
5
|
5
|
const scene = new THREE.Scene();
|
6
|
|
-var camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.1, 1000);
|
|
6
|
+const camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.1, 1000);
|
7
|
7
|
|
8
|
8
|
console.time("init geo");
|
9
|
|
-var geometry = new THREE.IcosahedronGeometry(10, 6);
|
|
9
|
+const geometry = new THREE.IcosahedronGeometry(10, 0);
|
10
|
10
|
console.timeEnd("init geo");
|
11
|
11
|
|
12
|
12
|
console.time("Hexsphere");
|
13
|
|
-var vertToFaces = {};
|
14
|
|
-var newVertices = [];
|
15
|
|
-var colors = [];
|
|
13
|
+const vertToFaces = {};
|
|
14
|
+const newVertices = [];
|
|
15
|
+const colors = [];
|
16
|
16
|
|
17
|
|
-for (var i = 0; i < geometry.faces.length; i += 1) {
|
18
|
|
- var face = geometry.faces[i];
|
|
17
|
+for (let i = 0; i < geometry.faces.length; i += 1) {
|
|
18
|
+ const face = geometry.faces[i];
|
19
|
19
|
|
20
|
20
|
if (vertToFaces[face.a]) {
|
21
|
21
|
vertToFaces[face.a].push(i);
|
|
@@ -36,69 +36,85 @@ for (var i = 0; i < geometry.faces.length; i += 1) {
|
36
|
36
|
}
|
37
|
37
|
}
|
38
|
38
|
|
39
|
|
-var originalVertCount = geometry.vertices.length;
|
40
|
|
-
|
41
|
|
-var faceCentroids = {};
|
42
|
|
-for (var i = 0; i < geometry.faces.length; i += 1) {
|
43
|
|
- var face = geometry.faces[i];
|
44
|
|
- var vertexA = geometry.vertices[face.a];
|
45
|
|
- var vertexB = geometry.vertices[face.b];
|
46
|
|
- var vertexC = geometry.vertices[face.c];
|
47
|
|
- var centroid = new THREE.Vector3(
|
48
|
|
- (vertexA.x + vertexB.x + vertexC.x) / 3,
|
49
|
|
- (vertexA.y + vertexB.y + vertexC.y) / 3,
|
50
|
|
- (vertexA.z + vertexB.z + vertexC.z) / 3,
|
51
|
|
- );
|
|
39
|
+const originalVertCount = geometry.vertices.length;
|
|
40
|
+
|
|
41
|
+const faceCentroids = {};
|
|
42
|
+for (let i = 0; i < geometry.faces.length; i += 1) {
|
|
43
|
+ const face = geometry.faces[i];
|
|
44
|
+ const vertexA = geometry.vertices[face.a];
|
|
45
|
+ const vertexB = geometry.vertices[face.b];
|
|
46
|
+ const vertexC = geometry.vertices[face.c];
|
|
47
|
+ // var centroid = new THREE.Vector3(
|
|
48
|
+ // (vertexA.x + vertexB.x + vertexC.x) / 3,
|
|
49
|
+ // (vertexA.y + vertexB.y + vertexC.y) / 3,
|
|
50
|
+ // (vertexA.z + vertexB.z + vertexC.z) / 3,
|
|
51
|
+ // );
|
|
52
|
+ const vabHalf = vertexB.clone().sub(vertexA).divideScalar(2);
|
|
53
|
+ const pabHalf = vertexA.clone().add(vabHalf);
|
|
54
|
+ const centroid = vertexC.clone().sub(pabHalf).multiplyScalar(1/3).add(pabHalf);
|
52
|
55
|
|
53
|
56
|
// var centroidIndex = (newVertices.push(centroid.x, centroid.y, centroid.z) / 3) - 1;
|
54
|
57
|
faceCentroids[i] = centroid;
|
55
|
58
|
}
|
56
|
59
|
|
|
60
|
+const findAdjacentFace = (vertexIndex, faces) => {
|
|
61
|
+ for (let i = 0; i < faces.length; i += 1) {
|
|
62
|
+ const faceIndex = faces[i];
|
|
63
|
+ const face = geometry.faces[faceIndex];
|
|
64
|
+ if ([face.a, face.b, face.c].includes(vertexIndex)) return faceIndex;
|
|
65
|
+ }
|
|
66
|
+}
|
|
67
|
+
|
57
|
68
|
console.time("dual");
|
58
|
|
-var midVertCache = {};
|
59
|
|
-var hexCount = 0;
|
60
|
|
-var pentCount = 0;
|
61
|
|
-for (var i = 0; i < originalVertCount; i += 1) {
|
62
|
|
- var faces = vertToFaces[i];
|
|
69
|
+const midVertCache = {};
|
|
70
|
+let hexCount = 0;
|
|
71
|
+let pentCount = 0;
|
|
72
|
+for (let i = 0; i < originalVertCount; i += 1) {
|
|
73
|
+ const faces = vertToFaces[i];
|
63
|
74
|
if (faces.length === 6) {
|
64
|
75
|
hexCount += 1;
|
65
|
76
|
} else if (faces.length === 5) {
|
66
|
77
|
pentCount += 1;
|
67
|
78
|
}
|
68
|
|
- var color = new THREE.Color(Math.random(), Math.random(), Math.random());
|
69
|
|
- for (var j = 0; j < faces.length; j += 1) {
|
70
|
|
- var faceIndex = faces[j];
|
71
|
|
- var face = geometry.faces[faceIndex];
|
72
|
|
- var nonCenterVerts = [face.a, face.b, face.c].filter(vert => vert !== i);
|
73
|
|
- var sortedFace = new THREE.Face3(i, nonCenterVerts[0], nonCenterVerts[1]);
|
74
|
|
- // var sortedFace = face;
|
75
|
|
-
|
76
|
|
- var vertexA = geometry.vertices[sortedFace.a];
|
77
|
|
- var vertexB = geometry.vertices[sortedFace.b];
|
78
|
|
- var vertexC = geometry.vertices[sortedFace.c];
|
79
|
|
-
|
80
|
|
- var midABKey = sortedFace.a + "," + sortedFace.b
|
81
|
|
- var midAB = midVertCache[midABKey];
|
82
|
|
- if (!midAB) {
|
83
|
|
- midAB = vertexA.clone().lerp(vertexB, 0.5);
|
84
|
|
- midVertCache[midABKey] = midAB;
|
|
79
|
+ const color = new THREE.Color(Math.random(), Math.random(), Math.random());
|
|
80
|
+ for (let j = 0; j < faces.length; j += 1) {
|
|
81
|
+ const faceIndex = faces[j];
|
|
82
|
+ const face = geometry.faces[faceIndex];
|
|
83
|
+ const sortedVerts = [face.a, face.b, face.c].filter(vert => vert !== i);
|
|
84
|
+ sortedVerts.unshift(i)
|
|
85
|
+
|
|
86
|
+ const vertexA = geometry.vertices[sortedVerts[0]];
|
|
87
|
+ const vertexB = geometry.vertices[sortedVerts[1]];
|
|
88
|
+ const vertexC = geometry.vertices[sortedVerts[2]];
|
|
89
|
+
|
|
90
|
+ const centroid = faceCentroids[faceIndex];
|
|
91
|
+
|
|
92
|
+ const adjBFace = findAdjacentFace(sortedVerts[1], faces);
|
|
93
|
+ const adjBCentroid = faceCentroids[adjBFace];
|
|
94
|
+ const midBCentroidKey = sortedVerts[1] + ",F" + adjBFace;
|
|
95
|
+ let midBCentroid = midVertCache[midBCentroidKey];
|
|
96
|
+ if (!midBCentroid) {
|
|
97
|
+ midBCentroid = centroid.clone().lerp(adjBCentroid, 0.5);
|
|
98
|
+ midVertCache[midBCentroidKey] = midBCentroid;
|
85
|
99
|
}
|
86
|
|
- var midACKey = sortedFace.a + "," + sortedFace.c
|
87
|
|
- var midAC = midVertCache[midACKey];
|
88
|
|
- if (!midAC) {
|
89
|
|
- midAC = vertexA.clone().lerp(vertexC, 0.5);
|
90
|
|
- midVertCache[midACKey] = midAC;
|
|
100
|
+
|
|
101
|
+ const adjCFace = findAdjacentFace(sortedVerts[2], faces);
|
|
102
|
+ const adjCCentroid = faceCentroids[adjCFace];
|
|
103
|
+ const midCCentroidKey = sortedVerts[2] + ",F" + adjCFace;
|
|
104
|
+ let midCCentroid = midVertCache[midCCentroidKey];
|
|
105
|
+ if (!midCCentroid) {
|
|
106
|
+ midCCentroid = centroid.clone().lerp(adjCCentroid, 0.5);
|
|
107
|
+ midVertCache[midCCentroidKey] = midCCentroid;
|
91
|
108
|
}
|
92
|
|
- var centroid = faceCentroids[faceIndex];
|
93
|
109
|
|
94
|
110
|
newVertices.push(
|
95
|
111
|
vertexA.x, vertexA.y, vertexA.z,
|
96
|
112
|
centroid.x, centroid.y, centroid.z,
|
97
|
|
- midAB.x, midAB.y, midAB.z,
|
|
113
|
+ midBCentroid.x, midBCentroid.y, midBCentroid.z,
|
98
|
114
|
|
99
|
115
|
vertexA.x, vertexA.y, vertexA.z,
|
100
|
116
|
centroid.x, centroid.y, centroid.z,
|
101
|
|
- midAC.x, midAC.y, midAC.z,
|
|
117
|
+ midCCentroid.x, midCCentroid.y, midCCentroid.z,
|
102
|
118
|
);
|
103
|
119
|
|
104
|
120
|
colors.push(
|
|
@@ -121,7 +137,7 @@ function disposeArray() {
|
121
|
137
|
}
|
122
|
138
|
|
123
|
139
|
console.time("find geo");
|
124
|
|
-var newGeometry = new THREE.BufferGeometry();
|
|
140
|
+const newGeometry = new THREE.BufferGeometry();
|
125
|
141
|
newGeometry.addAttribute("position", new THREE.Float32BufferAttribute(newVertices, 3));
|
126
|
142
|
newGeometry.addAttribute("color", new THREE.Float32BufferAttribute(colors, 3));
|
127
|
143
|
// newGeometry.computeFaceNormals();
|
|
@@ -131,16 +147,16 @@ console.timeEnd("find geo");
|
131
|
147
|
|
132
|
148
|
|
133
|
149
|
console.time("other render");
|
134
|
|
-var material = new THREE.MeshBasicMaterial({ vertexColors: THREE.VertexColors, side: THREE.DoubleSide });
|
135
|
|
-var sphere = new THREE.Mesh(newGeometry, material);
|
|
150
|
+const material = new THREE.MeshBasicMaterial({ vertexColors: THREE.VertexColors, side: THREE.DoubleSide });
|
|
151
|
+const sphere = new THREE.Mesh(newGeometry, material);
|
136
|
152
|
scene.add(sphere);
|
137
|
153
|
|
138
|
|
-var controls = new OrbitControls(camera);
|
|
154
|
+const controls = new OrbitControls(camera);
|
139
|
155
|
|
140
|
156
|
camera.position.z = 15;
|
141
|
157
|
controls.update()
|
142
|
158
|
|
143
|
|
-var renderer = new THREE.WebGLRenderer();
|
|
159
|
+const renderer = new THREE.WebGLRenderer();
|
144
|
160
|
renderer.setSize( window.innerWidth, window.innerHeight );
|
145
|
161
|
document.body.appendChild( renderer.domElement );
|
146
|
162
|
console.timeEnd("other render");
|