123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755 |
- import { Vector3, TmpVectors } from "../Maths/math.vector.js";
- import { Scalar } from "../Maths/math.scalar.js";
- import { PHI } from "../Maths/math.constants.js";
- import { _IsoVector } from "../Maths/math.isovector.js";
- /**
- * Class representing data for one face OAB of an equilateral icosahedron
- * When O is the isovector (0, 0), A is isovector (m, n)
- * @internal
- */
- // eslint-disable-next-line @typescript-eslint/naming-convention
- export class _PrimaryIsoTriangle {
- constructor() {
- this.cartesian = [];
- this.vertices = [];
- this.max = [];
- this.min = [];
- this.closestTo = [];
- this.innerFacets = [];
- this.isoVecsABOB = [];
- this.isoVecsOBOA = [];
- this.isoVecsBAOA = [];
- this.vertexTypes = [];
- // eslint-disable-next-line @typescript-eslint/naming-convention
- this.IDATA = new PolyhedronData("icosahedron", "Regular", [
- [0, PHI, -1],
- [-PHI, 1, 0],
- [-1, 0, -PHI],
- [1, 0, -PHI],
- [PHI, 1, 0],
- [0, PHI, 1],
- [-1, 0, PHI],
- [-PHI, -1, 0],
- [0, -PHI, -1],
- [PHI, -1, 0],
- [1, 0, PHI],
- [0, -PHI, 1],
- ], [
- [0, 2, 1],
- [0, 3, 2],
- [0, 4, 3],
- [0, 5, 4],
- [0, 1, 5],
- [7, 6, 1],
- [8, 7, 2],
- [9, 8, 3],
- [10, 9, 4],
- [6, 10, 5],
- [2, 7, 1],
- [3, 8, 2],
- [4, 9, 3],
- [5, 10, 4],
- [1, 6, 5],
- [11, 6, 7],
- [11, 7, 8],
- [11, 8, 9],
- [11, 9, 10],
- [11, 10, 6],
- ]);
- }
- /**
- * Creates the PrimaryIsoTriangle Triangle OAB
- * @param m an integer
- * @param n an integer
- */
- //operators
- setIndices() {
- let indexCount = 12; // 12 vertices already assigned
- const vecToidx = {}; //maps iso-vectors to indexCount;
- const m = this.m;
- const n = this.n;
- let g = m; // hcf of m, n when n != 0
- let m1 = 1;
- let n1 = 0;
- if (n !== 0) {
- g = Scalar.HCF(m, n);
- }
- m1 = m / g;
- n1 = n / g;
- let fr; //face to the right of current face
- let rot; //rotation about which vertex for fr
- let O;
- let A;
- let B;
- const oVec = _IsoVector.Zero();
- const aVec = new _IsoVector(m, n);
- const bVec = new _IsoVector(-n, m + n);
- const oaVec = _IsoVector.Zero();
- const abVec = _IsoVector.Zero();
- const obVec = _IsoVector.Zero();
- let verts = [];
- let idx;
- let idxR;
- let isoId;
- let isoIdR;
- const closestTo = [];
- const vDist = this.vertByDist;
- const matchIdx = (f, fr, isoId, isoIdR) => {
- idx = f + "|" + isoId;
- idxR = fr + "|" + isoIdR;
- if (!(idx in vecToidx || idxR in vecToidx)) {
- vecToidx[idx] = indexCount;
- vecToidx[idxR] = indexCount;
- indexCount++;
- }
- else if (idx in vecToidx && !(idxR in vecToidx)) {
- vecToidx[idxR] = vecToidx[idx];
- }
- else if (idxR in vecToidx && !(idx in vecToidx)) {
- vecToidx[idx] = vecToidx[idxR];
- }
- if (vDist[isoId][0] > 2) {
- closestTo[vecToidx[idx]] = [-vDist[isoId][0], vDist[isoId][1], vecToidx[idx]];
- }
- else {
- closestTo[vecToidx[idx]] = [verts[vDist[isoId][0]], vDist[isoId][1], vecToidx[idx]];
- }
- };
- this.IDATA.edgematch = [
- [1, "B"],
- [2, "B"],
- [3, "B"],
- [4, "B"],
- [0, "B"],
- [10, "O", 14, "A"],
- [11, "O", 10, "A"],
- [12, "O", 11, "A"],
- [13, "O", 12, "A"],
- [14, "O", 13, "A"],
- [0, "O"],
- [1, "O"],
- [2, "O"],
- [3, "O"],
- [4, "O"],
- [19, "B", 5, "A"],
- [15, "B", 6, "A"],
- [16, "B", 7, "A"],
- [17, "B", 8, "A"],
- [18, "B", 9, "A"],
- ];
- /***edges AB to OB***** rotation about B*/
- for (let f = 0; f < 20; f++) {
- //f current face
- verts = this.IDATA.face[f];
- O = verts[2];
- A = verts[1];
- B = verts[0];
- isoId = oVec.x + "|" + oVec.y;
- idx = f + "|" + isoId;
- if (!(idx in vecToidx)) {
- vecToidx[idx] = O;
- closestTo[O] = [verts[vDist[isoId][0]], vDist[isoId][1]];
- }
- isoId = aVec.x + "|" + aVec.y;
- idx = f + "|" + isoId;
- if (!(idx in vecToidx)) {
- vecToidx[idx] = A;
- closestTo[A] = [verts[vDist[isoId][0]], vDist[isoId][1]];
- }
- isoId = bVec.x + "|" + bVec.y;
- idx = f + "|" + isoId;
- if (!(idx in vecToidx)) {
- vecToidx[idx] = B;
- closestTo[B] = [verts[vDist[isoId][0]], vDist[isoId][1]];
- }
- //for edge vertices
- fr = this.IDATA.edgematch[f][0];
- rot = this.IDATA.edgematch[f][1];
- if (rot === "B") {
- for (let i = 1; i < g; i++) {
- abVec.x = m - i * (m1 + n1);
- abVec.y = n + i * m1;
- obVec.x = -i * n1;
- obVec.y = i * (m1 + n1);
- isoId = abVec.x + "|" + abVec.y;
- isoIdR = obVec.x + "|" + obVec.y;
- matchIdx(f, fr, isoId, isoIdR);
- }
- }
- if (rot === "O") {
- for (let i = 1; i < g; i++) {
- obVec.x = -i * n1;
- obVec.y = i * (m1 + n1);
- oaVec.x = i * m1;
- oaVec.y = i * n1;
- isoId = obVec.x + "|" + obVec.y;
- isoIdR = oaVec.x + "|" + oaVec.y;
- matchIdx(f, fr, isoId, isoIdR);
- }
- }
- fr = this.IDATA.edgematch[f][2];
- rot = this.IDATA.edgematch[f][3];
- if (rot && rot === "A") {
- for (let i = 1; i < g; i++) {
- oaVec.x = i * m1;
- oaVec.y = i * n1;
- abVec.x = m - (g - i) * (m1 + n1); //reversed for BA
- abVec.y = n + (g - i) * m1; //reversed for BA
- isoId = oaVec.x + "|" + oaVec.y;
- isoIdR = abVec.x + "|" + abVec.y;
- matchIdx(f, fr, isoId, isoIdR);
- }
- }
- for (let i = 0; i < this.vertices.length; i++) {
- isoId = this.vertices[i].x + "|" + this.vertices[i].y;
- idx = f + "|" + isoId;
- if (!(idx in vecToidx)) {
- vecToidx[idx] = indexCount++;
- if (vDist[isoId][0] > 2) {
- closestTo[vecToidx[idx]] = [-vDist[isoId][0], vDist[isoId][1], vecToidx[idx]];
- }
- else {
- closestTo[vecToidx[idx]] = [verts[vDist[isoId][0]], vDist[isoId][1], vecToidx[idx]];
- }
- }
- }
- }
- this.closestTo = closestTo;
- this.vecToidx = vecToidx;
- }
- calcCoeffs() {
- const m = this.m;
- const n = this.n;
- const thirdR3 = Math.sqrt(3) / 3;
- const LSQD = m * m + n * n + m * n;
- this.coau = (m + n) / LSQD;
- this.cobu = -n / LSQD;
- this.coav = (-thirdR3 * (m - n)) / LSQD;
- this.cobv = (thirdR3 * (2 * m + n)) / LSQD;
- }
- createInnerFacets() {
- const m = this.m;
- const n = this.n;
- for (let y = 0; y < n + m + 1; y++) {
- for (let x = this.min[y]; x < this.max[y] + 1; x++) {
- if (x < this.max[y] && x < this.max[y + 1] + 1) {
- this.innerFacets.push(["|" + x + "|" + y, "|" + x + "|" + (y + 1), "|" + (x + 1) + "|" + y]);
- }
- if (y > 0 && x < this.max[y - 1] && x + 1 < this.max[y] + 1) {
- this.innerFacets.push(["|" + x + "|" + y, "|" + (x + 1) + "|" + y, "|" + (x + 1) + "|" + (y - 1)]);
- }
- }
- }
- }
- edgeVecsABOB() {
- const m = this.m;
- const n = this.n;
- const B = new _IsoVector(-n, m + n);
- for (let y = 1; y < m + n; y++) {
- const point = new _IsoVector(this.min[y], y);
- const prev = new _IsoVector(this.min[y - 1], y - 1);
- const next = new _IsoVector(this.min[y + 1], y + 1);
- const pointR = point.clone();
- const prevR = prev.clone();
- const nextR = next.clone();
- pointR.rotate60About(B);
- prevR.rotate60About(B);
- nextR.rotate60About(B);
- const maxPoint = new _IsoVector(this.max[pointR.y], pointR.y);
- const maxPrev = new _IsoVector(this.max[pointR.y - 1], pointR.y - 1);
- const maxLeftPrev = new _IsoVector(this.max[pointR.y - 1] - 1, pointR.y - 1);
- if (pointR.x !== maxPoint.x || pointR.y !== maxPoint.y) {
- if (pointR.x !== maxPrev.x) {
- // type2
- //up
- this.vertexTypes.push([1, 0, 0]);
- this.isoVecsABOB.push([point, maxPrev, maxLeftPrev]);
- //down
- this.vertexTypes.push([1, 0, 0]);
- this.isoVecsABOB.push([point, maxLeftPrev, maxPoint]);
- }
- else if (pointR.y === nextR.y) {
- // type1
- //up
- this.vertexTypes.push([1, 1, 0]);
- this.isoVecsABOB.push([point, prev, maxPrev]);
- //down
- this.vertexTypes.push([1, 0, 1]);
- this.isoVecsABOB.push([point, maxPrev, next]);
- }
- else {
- // type 0
- //up
- this.vertexTypes.push([1, 1, 0]);
- this.isoVecsABOB.push([point, prev, maxPrev]);
- //down
- this.vertexTypes.push([1, 0, 0]);
- this.isoVecsABOB.push([point, maxPrev, maxPoint]);
- }
- }
- }
- }
- mapABOBtoOBOA() {
- const point = new _IsoVector(0, 0);
- for (let i = 0; i < this.isoVecsABOB.length; i++) {
- const temp = [];
- for (let j = 0; j < 3; j++) {
- point.x = this.isoVecsABOB[i][j].x;
- point.y = this.isoVecsABOB[i][j].y;
- if (this.vertexTypes[i][j] === 0) {
- point.rotateNeg120(this.m, this.n);
- }
- temp.push(point.clone());
- }
- this.isoVecsOBOA.push(temp);
- }
- }
- mapABOBtoBAOA() {
- const point = new _IsoVector(0, 0);
- for (let i = 0; i < this.isoVecsABOB.length; i++) {
- const temp = [];
- for (let j = 0; j < 3; j++) {
- point.x = this.isoVecsABOB[i][j].x;
- point.y = this.isoVecsABOB[i][j].y;
- if (this.vertexTypes[i][j] === 1) {
- point.rotate120(this.m, this.n);
- }
- temp.push(point.clone());
- }
- this.isoVecsBAOA.push(temp);
- }
- }
- // eslint-disable-next-line @typescript-eslint/naming-convention
- MapToFace(faceNb, geodesicData) {
- const F = this.IDATA.face[faceNb];
- const oidx = F[2];
- const aidx = F[1];
- const bidx = F[0];
- const O = Vector3.FromArray(this.IDATA.vertex[oidx]);
- const A = Vector3.FromArray(this.IDATA.vertex[aidx]);
- const B = Vector3.FromArray(this.IDATA.vertex[bidx]);
- const OA = A.subtract(O);
- const OB = B.subtract(O);
- const x = OA.scale(this.coau).add(OB.scale(this.cobu));
- const y = OA.scale(this.coav).add(OB.scale(this.cobv));
- const mapped = [];
- let idx;
- let tempVec = TmpVectors.Vector3[0];
- for (let i = 0; i < this.cartesian.length; i++) {
- tempVec = x.scale(this.cartesian[i].x).add(y.scale(this.cartesian[i].y)).add(O);
- mapped[i] = [tempVec.x, tempVec.y, tempVec.z];
- idx = faceNb + "|" + this.vertices[i].x + "|" + this.vertices[i].y;
- geodesicData.vertex[this.vecToidx[idx]] = [tempVec.x, tempVec.y, tempVec.z];
- }
- }
- //statics
- /**Creates a primary triangle
- * @internal
- */
- build(m, n) {
- const vertices = [];
- const O = _IsoVector.Zero();
- const A = new _IsoVector(m, n);
- const B = new _IsoVector(-n, m + n);
- vertices.push(O, A, B);
- //max internal isoceles triangle vertices
- for (let y = n; y < m + 1; y++) {
- for (let x = 0; x < m + 1 - y; x++) {
- vertices.push(new _IsoVector(x, y));
- }
- }
- //shared vertices along edges when needed
- if (n > 0) {
- const g = Scalar.HCF(m, n);
- const m1 = m / g;
- const n1 = n / g;
- for (let i = 1; i < g; i++) {
- vertices.push(new _IsoVector(i * m1, i * n1)); //OA
- vertices.push(new _IsoVector(-i * n1, i * (m1 + n1))); //OB
- vertices.push(new _IsoVector(m - i * (m1 + n1), n + i * m1)); // AB
- }
- //lower rows vertices and their rotations
- const ratio = m / n;
- for (let y = 1; y < n; y++) {
- for (let x = 0; x < y * ratio; x++) {
- vertices.push(new _IsoVector(x, y));
- vertices.push(new _IsoVector(x, y).rotate120(m, n));
- vertices.push(new _IsoVector(x, y).rotateNeg120(m, n));
- }
- }
- }
- //order vertices by x and then y
- vertices.sort((a, b) => {
- return a.x - b.x;
- });
- vertices.sort((a, b) => {
- return a.y - b.y;
- });
- const min = new Array(m + n + 1);
- const max = new Array(m + n + 1);
- for (let i = 0; i < min.length; i++) {
- min[i] = Infinity;
- max[i] = -Infinity;
- }
- let y = 0;
- let x = 0;
- const len = vertices.length;
- for (let i = 0; i < len; i++) {
- x = vertices[i].x;
- y = vertices[i].y;
- min[y] = Math.min(x, min[y]);
- max[y] = Math.max(x, max[y]);
- }
- //calculates the distance of a vertex from a given primary vertex
- const distFrom = (vert, primVert) => {
- const v = vert.clone();
- if (primVert === "A") {
- v.rotateNeg120(m, n);
- }
- if (primVert === "B") {
- v.rotate120(m, n);
- }
- if (v.x < 0) {
- return v.y;
- }
- return v.x + v.y;
- };
- const cartesian = [];
- const distFromO = [];
- const distFromA = [];
- const distFromB = [];
- const vertByDist = {};
- const vertData = [];
- let closest = -1;
- let dist = -1;
- for (let i = 0; i < len; i++) {
- cartesian[i] = vertices[i].toCartesianOrigin(new _IsoVector(0, 0), 0.5);
- distFromO[i] = distFrom(vertices[i], "O");
- distFromA[i] = distFrom(vertices[i], "A");
- distFromB[i] = distFrom(vertices[i], "B");
- if (distFromO[i] === distFromA[i] && distFromA[i] === distFromB[i]) {
- closest = 3;
- dist = distFromO[i];
- }
- else if (distFromO[i] === distFromA[i]) {
- closest = 4;
- dist = distFromO[i];
- }
- else if (distFromA[i] === distFromB[i]) {
- closest = 5;
- dist = distFromA[i];
- }
- else if (distFromB[i] === distFromO[i]) {
- closest = 6;
- dist = distFromO[i];
- }
- if (distFromO[i] < distFromA[i] && distFromO[i] < distFromB[i]) {
- closest = 2;
- dist = distFromO[i];
- }
- if (distFromA[i] < distFromO[i] && distFromA[i] < distFromB[i]) {
- closest = 1;
- dist = distFromA[i];
- }
- if (distFromB[i] < distFromA[i] && distFromB[i] < distFromO[i]) {
- closest = 0;
- dist = distFromB[i];
- }
- vertData.push([closest, dist, vertices[i].x, vertices[i].y]);
- }
- vertData.sort((a, b) => {
- return a[2] - b[2];
- });
- vertData.sort((a, b) => {
- return a[3] - b[3];
- });
- vertData.sort((a, b) => {
- return a[1] - b[1];
- });
- vertData.sort((a, b) => {
- return a[0] - b[0];
- });
- for (let v = 0; v < vertData.length; v++) {
- vertByDist[vertData[v][2] + "|" + vertData[v][3]] = [vertData[v][0], vertData[v][1], v];
- }
- this.m = m;
- this.n = n;
- this.vertices = vertices;
- this.vertByDist = vertByDist;
- this.cartesian = cartesian;
- this.min = min;
- this.max = max;
- return this;
- }
- }
- /** Builds Polyhedron Data
- * @internal
- */
- export class PolyhedronData {
- constructor(
- /**
- * The name of the polyhedron
- */
- name,
- /**
- * The category of the polyhedron
- */
- category,
- /**
- * vertex data
- */
- vertex,
- /**
- * face data
- */
- face) {
- this.name = name;
- this.category = category;
- this.vertex = vertex;
- this.face = face;
- }
- }
- /**
- * This class Extends the PolyhedronData Class to provide measures for a Geodesic Polyhedron
- */
- export class GeodesicData extends PolyhedronData {
- /**
- * @internal
- */
- innerToData(face, primTri) {
- for (let i = 0; i < primTri.innerFacets.length; i++) {
- this.face.push(primTri.innerFacets[i].map((el) => primTri.vecToidx[face + el]));
- }
- }
- /**
- * @internal
- */
- mapABOBtoDATA(faceNb, primTri) {
- const fr = primTri.IDATA.edgematch[faceNb][0];
- for (let i = 0; i < primTri.isoVecsABOB.length; i++) {
- const temp = [];
- for (let j = 0; j < 3; j++) {
- if (primTri.vertexTypes[i][j] === 0) {
- temp.push(faceNb + "|" + primTri.isoVecsABOB[i][j].x + "|" + primTri.isoVecsABOB[i][j].y);
- }
- else {
- temp.push(fr + "|" + primTri.isoVecsABOB[i][j].x + "|" + primTri.isoVecsABOB[i][j].y);
- }
- }
- this.face.push([primTri.vecToidx[temp[0]], primTri.vecToidx[temp[1]], primTri.vecToidx[temp[2]]]);
- }
- }
- /**
- * @internal
- */
- mapOBOAtoDATA(faceNb, primTri) {
- const fr = primTri.IDATA.edgematch[faceNb][0];
- for (let i = 0; i < primTri.isoVecsOBOA.length; i++) {
- const temp = [];
- for (let j = 0; j < 3; j++) {
- if (primTri.vertexTypes[i][j] === 1) {
- temp.push(faceNb + "|" + primTri.isoVecsOBOA[i][j].x + "|" + primTri.isoVecsOBOA[i][j].y);
- }
- else {
- temp.push(fr + "|" + primTri.isoVecsOBOA[i][j].x + "|" + primTri.isoVecsOBOA[i][j].y);
- }
- }
- this.face.push([primTri.vecToidx[temp[0]], primTri.vecToidx[temp[1]], primTri.vecToidx[temp[2]]]);
- }
- }
- /**
- * @internal
- */
- mapBAOAtoDATA(faceNb, primTri) {
- const fr = primTri.IDATA.edgematch[faceNb][2];
- for (let i = 0; i < primTri.isoVecsBAOA.length; i++) {
- const temp = [];
- for (let j = 0; j < 3; j++) {
- if (primTri.vertexTypes[i][j] === 1) {
- temp.push(faceNb + "|" + primTri.isoVecsBAOA[i][j].x + "|" + primTri.isoVecsBAOA[i][j].y);
- }
- else {
- temp.push(fr + "|" + primTri.isoVecsBAOA[i][j].x + "|" + primTri.isoVecsBAOA[i][j].y);
- }
- }
- this.face.push([primTri.vecToidx[temp[0]], primTri.vecToidx[temp[1]], primTri.vecToidx[temp[2]]]);
- }
- }
- /**
- * @internal
- */
- orderData(primTri) {
- const nearTo = [];
- for (let i = 0; i < 13; i++) {
- nearTo[i] = [];
- }
- const close = primTri.closestTo;
- for (let i = 0; i < close.length; i++) {
- if (close[i][0] > -1) {
- if (close[i][1] > 0) {
- nearTo[close[i][0]].push([i, close[i][1]]);
- }
- }
- else {
- nearTo[12].push([i, close[i][0]]);
- }
- }
- const near = [];
- for (let i = 0; i < 12; i++) {
- near[i] = i;
- }
- let nearIndex = 12;
- for (let i = 0; i < 12; i++) {
- nearTo[i].sort((a, b) => {
- return a[1] - b[1];
- });
- for (let j = 0; j < nearTo[i].length; j++) {
- near[nearTo[i][j][0]] = nearIndex++;
- }
- }
- for (let j = 0; j < nearTo[12].length; j++) {
- near[nearTo[12][j][0]] = nearIndex++;
- }
- for (let i = 0; i < this.vertex.length; i++) {
- this.vertex[i].push(near[i]);
- }
- this.vertex.sort((a, b) => {
- return a[3] - b[3];
- });
- for (let i = 0; i < this.vertex.length; i++) {
- this.vertex[i].pop();
- }
- for (let i = 0; i < this.face.length; i++) {
- for (let j = 0; j < this.face[i].length; j++) {
- this.face[i][j] = near[this.face[i][j]];
- }
- }
- this.sharedNodes = nearTo[12].length;
- this.poleNodes = this.vertex.length - this.sharedNodes;
- }
- /**
- * @internal
- */
- setOrder(m, faces) {
- const adjVerts = [];
- const dualFaces = [];
- let face = faces.pop();
- dualFaces.push(face);
- let index = this.face[face].indexOf(m);
- index = (index + 2) % 3;
- let v = this.face[face][index];
- adjVerts.push(v);
- let f = 0;
- while (faces.length > 0) {
- face = faces[f];
- if (this.face[face].indexOf(v) > -1) {
- // v is a vertex of face f
- index = (this.face[face].indexOf(v) + 1) % 3;
- v = this.face[face][index];
- adjVerts.push(v);
- dualFaces.push(face);
- faces.splice(f, 1);
- f = 0;
- }
- else {
- f++;
- }
- }
- this.adjacentFaces.push(adjVerts);
- return dualFaces;
- }
- /**
- * @internal
- */
- toGoldbergPolyhedronData() {
- const goldbergPolyhedronData = new PolyhedronData("GeoDual", "Goldberg", [], []);
- goldbergPolyhedronData.name = "GD dual";
- const verticesNb = this.vertex.length;
- const map = new Array(verticesNb);
- for (let v = 0; v < verticesNb; v++) {
- map[v] = [];
- }
- for (let f = 0; f < this.face.length; f++) {
- for (let i = 0; i < 3; i++) {
- map[this.face[f][i]].push(f);
- }
- }
- let cx = 0;
- let cy = 0;
- let cz = 0;
- let face = [];
- let vertex = [];
- this.adjacentFaces = [];
- for (let m = 0; m < map.length; m++) {
- goldbergPolyhedronData.face[m] = this.setOrder(m, map[m].concat([]));
- map[m].forEach((el) => {
- cx = 0;
- cy = 0;
- cz = 0;
- face = this.face[el];
- for (let i = 0; i < 3; i++) {
- vertex = this.vertex[face[i]];
- cx += vertex[0];
- cy += vertex[1];
- cz += vertex[2];
- }
- goldbergPolyhedronData.vertex[el] = [cx / 3, cy / 3, cz / 3];
- });
- }
- return goldbergPolyhedronData;
- }
- //statics
- /**Builds the data for a Geodesic Polyhedron from a primary triangle
- * @param primTri the primary triangle
- * @internal
- */
- static BuildGeodesicData(primTri) {
- const geodesicData = new GeodesicData("Geodesic-m-n", "Geodesic", [
- [0, PHI, -1],
- [-PHI, 1, 0],
- [-1, 0, -PHI],
- [1, 0, -PHI],
- [PHI, 1, 0],
- [0, PHI, 1],
- [-1, 0, PHI],
- [-PHI, -1, 0],
- [0, -PHI, -1],
- [PHI, -1, 0],
- [1, 0, PHI],
- [0, -PHI, 1],
- ], []);
- primTri.setIndices();
- primTri.calcCoeffs();
- primTri.createInnerFacets();
- primTri.edgeVecsABOB();
- primTri.mapABOBtoOBOA();
- primTri.mapABOBtoBAOA();
- for (let f = 0; f < primTri.IDATA.face.length; f++) {
- primTri.MapToFace(f, geodesicData);
- geodesicData.innerToData(f, primTri);
- if (primTri.IDATA.edgematch[f][1] === "B") {
- geodesicData.mapABOBtoDATA(f, primTri);
- }
- if (primTri.IDATA.edgematch[f][1] === "O") {
- geodesicData.mapOBOAtoDATA(f, primTri);
- }
- if (primTri.IDATA.edgematch[f][3] === "A") {
- geodesicData.mapBAOAtoDATA(f, primTri);
- }
- }
- geodesicData.orderData(primTri);
- const radius = 1;
- geodesicData.vertex = geodesicData.vertex.map(function (el) {
- const a = el[0];
- const b = el[1];
- const c = el[2];
- const d = Math.sqrt(a * a + b * b + c * c);
- el[0] *= radius / d;
- el[1] *= radius / d;
- el[2] *= radius / d;
- return el;
- });
- return geodesicData;
- }
- }
- //# sourceMappingURL=geodesicMesh.js.map
|