How to get triangles for AABB verts? - javascript

I am trying to render cubes to represent AABB's. In order to do this I need the vertices of the cube and the 'cells', or triangles. I have AABB structures that look like [vec3Min, vec3Max]. I am able to get the
8 vertices for the cube using the following
export function vertsFromAABB(aabb){
const min = aabb[0];
const max = aabb[1];
return [
// min Y axis verts
min,
[max[0],min[1],min[2]],
[max[0],min[1],max[2]],
[min[1],min[1],max[2]],
// max Y axis verts
max,
[min[0],max[1],max[2]],
[min[0],max[1],min[0]],
[max[0],max[1],min[0]]
];
}
I now need to get the triangle indexes from this set of vertices. The cells should be an array of vertex indicies eg [[0,1,2],[1,2,3], ...]
EDIT UPDATE
I have made the fixes to the last 2 verts that was suggested in the comments. I have a function inprogress for the cells that looks like
export function cellsFromAABBVerts(aabbVerts){
return [
// Top quad triangles
[0,1,2],
[1,2,3],
// Side?
[2,3,4],
[3,4,5],
// Bottom quad triangles
[4,5,6],
[5,6,7],
];
}

If you visualize your cuboid, like this:
then it is pretty straight-forward to derive the triangle indices:
[
[ 0, 1, 2 ],
[ 0, 2, 3 ],
[ 6, 5, 4 ],
[ 6, 4, 7 ],
[ 1, 7, 4 ],
[ 1, 4, 2 ],
[ 0, 3, 5 ],
[ 0, 5, 6 ],
[ 0, 6, 7 ],
[ 0, 7, 1 ],
[ 2, 4, 5 ],
[ 2, 5, 3 ]
]

Related

Adding elements from each sub array in a 2D array in Javascript

So I have this 2D permutations array of ints which looks like this:
arr = [
[ 5, 2, 6 ],
[ 2, 5, 6 ],
[ 6, 5, 2 ],
[ 5, 6, 2 ],
[ 2, 6, 5 ],
[ 6, 2, 5 ]
]
and essentially I want to be able to get a string that looks like this '652,625,562,526,256'
This means that the numbers are ordered and are in string format.
What I have done so far is:
arr.map(c => c.join("")).join()
Which combines it to a array, however now my thought process would be to convert this to a array of ints and then order and re-parse as strings, but there must be some kind of easier way to do this?
I'm quite new to JavaScript so any help is appreciated.
Don't do the second join immediately - instead, sort the array of joined strings first, then join:
const arr = [
[ 5, 2, 6 ],
[ 2, 5, 6 ],
[ 6, 5, 2 ],
[ 5, 6, 2 ],
[ 2, 6, 5 ],
[ 6, 2, 5 ]
];
const result = arr
.map(subarr => subarr.join(''))
.sort((a, b) => b.localeCompare(a, undefined, { numeric: true }))
.join();
console.log(result);
or map to numbers and subtract in the comparator:
const arr = [
[ 5, 2, 6 ],
[ 2, 5, 6 ],
[ 6, 5, 2 ],
[ 5, 6, 2 ],
[ 2, 6, 5 ],
[ 6, 2, 5 ]
];
const result = arr
.map(subarr => Number(subarr.join('')))
.sort((a, b) => b - a)
.join();
console.log(result);

Converting Python enumerate into Javascript

I am trying to convert a function of python code into JavaScript.
The arr variable is an array such as [2, 5, 3, 1]. Basically, I want to create a list of tuple where each tuple contains as first value the position of the element in the arr and as second value the element of the arr. Then, I want to do the same for the reversed of arr
Python code:
def myPositions(arr):
positions = sorted(list(enumerate(arr)), key=lambda e: e[1])
return positions
def final(arr):
print("Reversed", arr[::-1]) # [ 1, 3, 5, 2 ]
print(myPositions(arr)) # [(3, 1), (0, 2), (2, 3), (1, 5)]
print(myPositions(arr[::-1])) # [(0, 1), (3, 2), (1, 3), (2, 5)]
My JavaScript code
Since there is no enumerate in JavaScript (this is what I think), I did the following:
function myPositions(arr) {
let positions = arr.map((e,i) => [i, e]).sort((a, b) => a[1] - b[1] )
return positions
}
function final(arr) {
let reversedArr = arr.reverse()
console.log("Reversed", reversedArr) // [ 1, 3, 5, 2 ]
let x = myPositions(arr)
console.log(x) // [ [ 0, 1 ], [ 3, 2 ], [ 1, 3 ], [ 2, 5 ] ]
let y = myPositions(reversedArr)
console.log(y) // [ [ 0, 1 ], [ 3, 2 ], [ 1, 3 ], [ 2, 5 ] ] This is different than print(myPositions(arr[::-1]))
}
I do not get why it works the same if I do not reverse the array.
But with the reversed array, I get two different results.
In python I get [(0, 1), (3, 2), (1, 3), (2, 5)], in JS I get [ [ 0, 1 ], [ 3, 2 ], [ 1, 3 ], [ 2, 5 ] ]

Why does shifting an array within an array affect copied (not by reference) arrays, but shifting the whole initial array does not? (Javascript)

I am trying to shift an array and use that array, then set it to its original values using a copied array that was copied not by reference. For some reason, shifting arrays from the original array does not affect the copied array, but shifting elements from within arrays in the initial array does affect the copied array. How do I copy an array, modify it, use it, then set it back to its original form?
I originally was having trouble because I was copying by reference, but then I learned that using the rest operator allowed me to copy the array (not by reference). It seems the two datum are still linked.
var m = [[1,2,3],[4,5,6],[7,8,9]]
var matrix = [...m]
m.shift();
console.log(matrix);
m[0].shift();
console.log(m);
console.log(matrix);
Expected:
[ [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] ]
[ [ 5, 6 ], [ 7, 8, 9 ] ]
[ [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] ]
Actual:
[ [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] ]
[ [ 5, 6 ], [ 7, 8, 9 ] ]
[ [ 1, 2, 3 ], [ 5, 6 ], [ 7, 8, 9 ] ]
The problem is that the second degree arrays are still being passed by reference when you do [...m]. I'm not sure how you could still use the rest operator but another thing you could do is:
var matrix = JSON.parse(JSON.stringify(m));
to avoid the problem.
var m = [[1,2,3],[4,5,6],[7,8,9]];
var matrix = JSON.parse(JSON.stringify(m));
m.shift();
console.log(matrix);
m[0].shift();
console.log(m);
console.log(matrix);

JavaScript. Push and read from Multidimensional Array

I am trying to push values into a multidimensional array and read values out of it based on code that i've seen on other posts on this site. This is my array push code.
SelectedWindowGraphs.push([ContainerIDValue,elementID+"chkbox"]);
ContainerIDValue is an integer and elementID+"chkbox" is what i want to store at that position in the array. Here is what i saw when i debugged my code:
This is not what i want. At position 0, i want CUT17chkbox, CUT18chkbox, and CUT19chkbox. How do i fix my array so that i does that?
// initialize an array at that position in case it has not been defined yet
SelectedWindowGraphs[ContainerIDValue] = (SelectedWindowGraphs[ContainerIDValue] ||
[]);
// push the value at the desired position
SelectedWindowGraphs[ContainerIDValue].push(elementID+"chkbox");
You have to push to a subarray:
if(!SelectedWindowGraphs[ContainerIDValue])
SelectedWindowGraphs[ContainerIDValue] = [];
SelectedWindowGraphs[ContainerIDValue]
.push(elementID+"chkbox");
You could add elements at certain position just doing:
var arr = [ 1, 2, 3, 4, 5, 6, 7 ]
arr[2] = "three";
console.log(arr);//[ 1, 2, 'three', 4, 5, 6, 7 ]
In a multidimensional array:
var arr = [ 1, [2, 3, 4, 5, 6], 7 ]
arr[1][2] = "four";
console.log(arr);//[ 1, [ 2, 3, 'four', 5, 6 ], 7 ]
When you perform push you are adding one or more elements at the end.
var arr = [1,2,3]
arr.push(4,5);//you are adding 4 and then 5
console.log(arr);//[ 1, 2, 3, 4, 5 ]
In a multidimensional array:
var arr = [1,2,[3,4]]
arr[2].push(5,6);//position 2
console.log(arr);//[ 1, 2, [ 3, 4, 5, 6 ] ]
To insert an element in a specific position (and move right element n positions) you could use splice(). In the following case, 2th and 3th position
var arr = [ 1, 2, 3, 4, 5 ]
arr.splice(2, 0, 999, 8888);
console.log(arr);//[ 1, 999, 8888, 2, 3, 4, 5 ]
In a multidimensional array:
var arr = [ 1, 2, [3,4,5], 6, 7 ]
arr.splice(2, 0, [8,9,10]);
console.log(arr);//[ 1, 2, [ 8, 9, 10 ], [ 3, 4, 5 ], 6, 7 ]

Understanding the geometry of a truncated Icosahedron, for rendering

I'm trying to render a truncated icosahedron like above with clickable zones using Three.js.
I found the code for a regular icosahedron
var t = ( 1 + Math.sqrt( 5 ) ) / 2;
var vertices = [
[ -1, t, 0 ], [ 1, t, 0 ], [ -1, -t, 0 ], [ 1, -t, 0 ],
[ 0, -1, t ], [ 0, 1, t ], [ 0, -1, -t ], [ 0, 1, -t ],
[ t, 0, -1 ], [ t, 0, 1 ], [ -t, 0, -1 ], [ -t, 0, 1 ]
];
var faces = [
[ 0, 11, 5 ], [ 0, 5, 1 ], [ 0, 1, 7 ], [ 0, 7, 10 ], [ 0, 10, 11 ],
[ 1, 5, 9 ], [ 5, 11, 4 ], [ 11, 10, 2 ], [ 10, 7, 6 ], [ 7, 1, 8 ],
[ 3, 9, 4 ], [ 3, 4, 2 ], [ 3, 2, 6 ], [ 3, 6, 8 ], [ 3, 8, 9 ],
[ 4, 9, 5 ], [ 2, 4, 11 ], [ 6, 2, 10 ], [ 8, 6, 7 ], [ 9, 8, 1 ]
];
THREE.PolyhedronGeometry.call( this, vertices, faces, radius, detail );
And drew the conclusion that t is φ & vertices consists of all the permutations of:
(0, ±1, ±φ) (±1, ±φ, 0) (±φ, 0, ±1) - From Here
So I modified my vertices as per:
(0, ±1, ±3φ) (±2, ±(1+2φ), ±φ) (±1, ±(2+φ), ±2φ) - From Here
Resulting in:
var vertices = [
[-2, (1+2*t,t], [2,(1+2*t), t ], [-2,-(1+2*t),-t], [2,-(1+2*t),-t ],
[0,-1,3*t], [0,1,3*t], [0,-1,-3*t], [0,1,-3*t],
[1,-(2+t),-2*t ],[1,(2+t),2*t],[-1,-(2+t),-2*t],[-1,(2+t),2*t]
];
Now I understand I have to modify the faces as well. Icosahedron seems to have 20 triangular faces & I can construct any polygon in Three.js with triangles, only.
Does it then follow, that I need the coordinates for 5 pentagons & 12 hexagons in the form of:
5 * 12 + 6 * 20 = 180 triangles
If so, how should I proceed in generating those coordinates? Or even if I am wrong regarding the whole thing.
The JSModeler framework can generate a lot of solids, including truncated icosahedron, so maybe the source can help you.
You can find the code here if you find for GenerateTruncatedIcosahedron:
https://github.com/kovacsv/JSModeler/blob/master/src/extras/solidgenerator.js
The code creates polygons with five and six vertices, but it is easy to replace them with triangles.

Categories

Resources