TINTIN
TINTIN

Reputation: 183

ThreeJs : How can i add Tetrahedron geometry to the surface

I am new to Three js , I had learned few geometry , I want to create a Icosahedron geometry which have a tetrahedral on its face . But i dont know how can i achieve the structure , if anyone knows plz reply,

my icosahedron code

var Icosah = new THREE.Mesh(new THREE.IcosahedronGeometry(1,4), redMat);
scene.add(Icosah);

My geometry looks like:

enter image description here

geometry i want to achieve:

enter image description here

the geometry have tetrahedral on its face

P.S: if you think my approach of using Icosahedron to create the required geometry is wrong , than plz suggest the better approach so that it will help me to create the required geometry

Upvotes: 0

Views: 405

Answers (1)

prisoner849
prisoner849

Reputation: 17596

Here is a solution from the scratch.

Feel free to modify it at your will :)

body{
  overflow: hidden;
  margin: 0;
}
<script type="module">
console.clear();
import * as THREE from "https://cdn.skypack.dev/[email protected]/build/three.module.js";
import {OrbitControls} from "https://cdn.skypack.dev/[email protected]/examples/jsm/controls/OrbitControls.js";

THREE.BufferGeometry.prototype.tripleFace = tripleFace;

let scene = new THREE.Scene();
let camera = new THREE.PerspectiveCamera(60, innerWidth / innerHeight, 1, 1000);
camera.position.set(0, 0, 12);
let renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);

let controls = new OrbitControls(camera, renderer.domElement);

let light = new THREE.DirectionalLight(0xffffff, 1);
light.position.setScalar(1);
scene.add(light, new THREE.AmbientLight(0xffffff, 0.5));

let g = new THREE.IcosahedronGeometry(5, 5).tripleFace();
console.log(g);
let m = new THREE.MeshLambertMaterial({color: "aqua", wireframe: false});
let o = new THREE.Mesh(g, m);
scene.add(o);

let l = new THREE.Mesh(g, new THREE.MeshBasicMaterial({wireframe: true}));
l.scale.setScalar(1.002);
scene.add(l);

window.addEventListener("resize", () => {
  camera.aspect = innerWidth / innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(innerWidth, innerHeight);
});

renderer.setAnimationLoop(()=>{
  renderer.render(scene, camera);
});

function tripleFace(){
  let geometry = this;
  let pos = geometry.attributes.position;
  if (geometry.index != null) {
    console.log("Works for non-indexed geometries!");
    return;
  }
  
  let facesCount = pos.count / 3;
  
  let pts = [];
  let triangle = new THREE.Triangle();
  let a = new THREE.Vector3(), b = new THREE.Vector3, c = new THREE.Vector3();
  for(let i = 0; i < facesCount; i++){
    a.fromBufferAttribute(pos, i * 3 + 0);
    b.fromBufferAttribute(pos, i * 3 + 1);
    c.fromBufferAttribute(pos, i * 3 + 2);
    triangle.set(a, b, c);
    let o = new THREE.Vector3();
    triangle.getMidpoint(o);
    
    // make it tetrahedron-like
    let l = a.distanceTo(b);
    let h = Math.sqrt(3) / 2 * l * 0.125;// scale it at your will
                                        // remove 0.125 to get tetrahedrons
    let d = o.clone().normalize().setLength(h); 
    o.add(d);
    
    pts.push(
      o.clone(), a.clone(), b.clone(),
      o.clone(), b.clone(), c.clone(),
      o.clone(), c.clone(), a.clone()
    );
  }
  
  let g = new THREE.BufferGeometry().setFromPoints(pts);
  g.computeVertexNormals()
  return g;
}
</script>

Upvotes: 3

Related Questions