Creating a Pyraminx using triangular shapes

Attempting to create a Pyraminx, a tetrahedron made up of multiple triangles, through my coding. The approach I am taking may not be very precise. You can find my code here: https://codepen.io/jeffprod/pen/XWbBZLN.

The issue I'm facing is manually inputting the coordinates for the facesVectors. It seems to work fine for the yellow and blue sides, but positioning the red and green triangles is proving to be challenging.

Is there a simpler way to achieve this?

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, innerWidth / innerHeight, 1, 100);
camera.position.set(-2, 1, 3);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);

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

// Creating an equilateral triangle
const sideLength = 1
const x = 0
const y = 0
const geometry = new THREE.Geometry()
geometry.vertices.push(new THREE.Vector3(x, (Math.sqrt(3) / 2 * sideLength) - (sideLength / 2), 0))
geometry.vertices.push(new THREE.Vector3(x - (sideLength / 2), y - (sideLength / 2), 0))
geometry.vertices.push(new THREE.Vector3(x + (sideLength / 2), y - (sideLength / 2), 0))
geometry.faces.push(new THREE.Face3(0, 1, 2))

const facesColors = [
  0xFFFF00, // yellow
  0xFF0000, // red
  0x0000FF, // blue
  0x008000 // green
]

// 36 triangles forming the Pyraminx
// numbers represent indexes of facesColors 
const pos = [
  0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 3, 1, 1, 1, 2, 2, 2, 3, 3, 3, 1, 1, 1, 1, 1, 2, 3, 3, 3, 3, 3
]

// Vectors for each triangle forming the tetrahedron
const facesVectors = [
  [0, 0, -1.5],
  [-0.52, 0, -0.6],
  [0, 0, -0.48],
  [0.52, 0, -0.6],
  [-1.04, 0, 0.3],
  [-0.52, 0, 0.42],
  [0, 0, 0.3],
  [0.52, 0, 0.42],
  [1.04, 0, 0.3],
  [-1.2, -0.16, 0.2],
  [-1.04, -0.45, 0.55],
  [-0.52, -0.34, 0.62],
  [0, -0.45, 0.55],
  [0.52, -0.34, 0.62],
  [1.04, -0.45, 0.55],
  [1.2, -0.16, 0.15],
  [-0.6, -0.16, -0.7],
  [-0.9, -0.3, -0.1],
  [-0.5, -0.5, -0.5]
]

for (let i = 0; i < facesVectors.length; i++) {
  material = new THREE.MeshBasicMaterial({ color: facesColors[pos[i]] })
  face = new THREE.Mesh(geometry, material)
  face.position.set(facesVectors[i][0], facesVectors[i][1], facesVectors[i][2])
  // Applying rotations
  if ([0, 1, 2, 3, 4, 5, 6, 7, 8].includes(i)) {
    face.rotation.x = -(Math.PI / 2)
  }
  if ([2, 5, 7, 10, 12, 14].includes(i)) { // 180 degrees
    face.rotation.z = Math.PI
  }
  if ([9, 16, 17, 18, 25, 26, 27, 28, 29].includes(i)) {
    if (i === 17) {
      face.rotation.x = -(1 * Math.PI) / 6
      face.rotation.y = -(2 * Math.PI) / 3
      face.rotation.z = -(1 * Math.PI) / 6
    } else {
      face.rotation.x = -Math.PI / 6
      face.rotation.y = -2 * Math.PI / 3
      face.rotation.z = Math.PI / 6
    }
  }
  if ([15, 22, 23, 24, 31, 32, 33, 34, 35].includes(i)) {
    face.rotation.x = -Math.PI / 6
    face.rotation.y = 2 * Math.PI / 3
    face.rotation.z = -Math.PI / 6
  } else if ([10, 11, 12, 13, 14, 19, 20, 21, 30].includes(i)) {
    face.rotation.x = Math.PI / 6
  }
  scene.add(face)
}

renderer.setAnimationLoop(() => {
  renderer.render(scene, camera);
});
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>

Answer №1

The four corner points that define a Tetrahedron are:

let s_8_9 = Math.sqrt(8/9), s_2_9 = Math.sqrt(2/9), s_2_3 = Math.sqrt(2/3);
let v = [
    new THREE.Vector3(0,0,1),
    new THREE.Vector3(s_8_9,0,-1/3),
    new THREE.Vector3(-s_2_9,s_2_3,-1/3),
    new THREE.Vector3(-s_2_9,-s_2_3,-1/3) 
];

To find a point on an edge using THREE.Vector3().lerpVectors:

let pointOnEdge = (pt1, pt2, t) => new THREE.Vector3().lerpVectors(pt1, pt2, t);

The inward offset points of a triangular face can be calculated as follows:

let computeOffsetPts = (pts, d) => {
    let offsetPts = [];
    for (let i = 0; i < pts.length; ++i) {
        let va = pointOnEdge(pts[i], pts[(i+1) % 3], d);
        let vb = pointOnEdge(pts[i], pts[(i+2) % 3], d); 
        offsetPts.push(new THREE.Vector3().lerpVectors(va, vb, 0.5)); 
    }
    return offsetPts;
}

These points can then be used to create the mesh. Example code:

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, innerWidth / innerHeight, 1, 100);
camera.position.set(-2, 1, 3);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);

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

const facesColors = [
  0xFFFF00, // yellow
  0xFF0000, // red
  0x0000FF, // blue
  0x008000 // green
]

// Continuing code omitted for brevity...

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Exploring the behavior of Object.assign in for loops and forEach loops

I've come across an interesting anomaly with Object.assign in the following scenario. function sampleFunction(index, myList) { myList.forEach((element, i) => { if (i === index) { console.log(Object.assign({}, {"newKey": " ...

Loop through the elements of one array using the indexes from a second array

Hey there! I need help with the following code snippet: let names = ["josh", "tony", "daniel"]; let arrayplaces = ["30", "60", "90"]; names.forEach((elem, indexed) => { const num2 = arrayp ...

navigate to a new page in vue with node.js

As I continue to expand my knowledge in JavaScript, Vue, and Node.js, I encountered a specific issue that I need help with. My goal is to redirect the Vue page after logging in using Node.js. Below you'll find the code snippets for my Vue setup and sc ...

What are the steps to install node.js on hosting servers like Hostinger, JustHost, and others?

Recently, I've been diving into the world of Node.js. While I have some experience with PHP, I've found that most hosting services already have a PHP interpreter installed, making it easy to work with. However, I'm now trying to figure out i ...

How to toggle visibility of a Bootstrap modal using VueJS (using CDN) without displaying the overlay

I have integrated VueJS into a single page using the CDN, which prevents me from utilizing bootstrap-vue. The functionality to display and hide a modal based on the value of the showModal data is currently working. However, the gray overlay surrounding th ...

Changing the z-index property of a Material-UI <Select> dropdown: What you need to know

Currently, I am implementing an <AppBar> with a significantly high z-index value (using withStyles, it is set to theme.zIndex.modal + 2 which results in 1202). The primary purpose behind this decision is to guarantee that my <Drawer> component ...

Module Ionic not found

When I attempt to run the command "ionic info", an error is displayed: [ERROR] Error loading @ionic/react package.json: Error: Cannot find module '@ionic/react/package' Below is the output of my ionic info: C:\Users\MyPC>ionic i ...

Utilize the function with another function (difficult to articulate)

Apologies in advance for my beginner question. Review the code snippet below: var dt = new Date(t*1000); var m = "0" + dt.getMinutes(); Depending on the t variable (unix time), the output can be one of the following: m = 054 // 54 minutes m = 03 // 3 min ...

Why is the autocomplete minlength and maxheight not functioning properly in MVC?

After entering a value in the text field, data from the database appears but adjusting the height and width of the list box seems to be a challenge. I have set the parameters like minLength: 0, maxItem: 5, but it doesn't seem to make a difference. ...

JavaScript issue with confirm/redirect feature not functioning as expected

A demonstration of JavaScript is utilized for deleting an employee in this scenario... <script type="text/javascript"> function deleteEmployee(employee) { var confirmation = confirm('Are you sure?'); if(confirmation) { ...

NextAuth credentials are undefined and authentication is malfunctioning in React

I encountered the following issue: https://i.sstatic.net/3VBoJ.png This is the code snippet that I am using: return ( <> {Object.values(providers).map((provider) => { if (provider.id === "credentials") { ret ...

Canvas with a button placed on top

I am working with a canvas and trying to position an HTML element over it using CSS. My goal is for the button to remain in place on the canvas even when resizing the entire page. Here is the code I am currently using. https://jsfiddle.net/z4fhrhLc/ #but ...

Looking for a way to extract a dynamic URL from a website's div element?

Is there a way for my app to load dynamically by extracting and reading the changing URL from a webpage? //webpage <div style="display:none" id="urladdress"> //dynamic url **https://freeuk30.listen2myradio.co ...

The syntax for specifying the post body content in frisby.js is important

My current setup involves smooth UI and server data exchange, but I am interested in exploring new development possibilities with Frisby.js. The UI utilizes a JavaScript form manager powered by jQuery. To send the request body, I first serialize a JavaScri ...

Converting data types when transferring a JavaScript variable to a PHP variable

I have a boolean value stored in a JavaScript variable var value=true; alert(typeof(value)); //Output: boolean I need to pass this variable to a PHP file through AJAX $.ajax({ type: 'POST', data: {value:value}, url: 'ajax.php& ...

Conceal an element along with its space, then signal the application to show alternative content using React

Greetings everyone! I seek assistance with a React Application that I am currently developing. As a newcomer to the Javascript world, I apologize if my inquiry seems trivial. The application comprises of two main elements: a loader, implemented as a React ...

Creating 3D models in three.js

Working with a 3D point cloud data in three.js, I have successfully added points to a Geometry using Vector3. Now I am looking to create surfaces from these points. for(var key in dt) { var hole = dt[key]; var pX = hole['x'] - planeMinX; var pY ...

How can I change the orientation of a cube using d3js?

Seeking guidance on creating an accurate chart using d3js How can I rotate the SVG to display the opposite angle as shown in the image? Any recommended resources for achieving this desired result would be greatly appreciated. The provided code only disp ...

When using the require() function in Node.js, the period "." is not being recognized as part of the command and

I recently encountered a problem while working on my project and reorganizing my files. I noticed that the "." in my requires are not being parsed correctly. Upon running my program, an error message is displayed: Error: Module './src/map/createMa ...

Creating a multi-dimensional array in order to store multiple sets of data

To generate a multidimensional array similar to the example below: var serviceCoors = [ [50, 40], [50, 50], [50, 60], ]; We have elements with latitude and longitude data: <div data-latitude="10" data-longitude="20" clas ...