3D polyhedron builder

Discuss interdimensional programming, Java applets and so forth.

3D polyhedron builder

Postby mr_e_man » Fri Jun 14, 2019 7:30 am

I just made this today. I haven't played with it or tested it much yet, but I hope to improve it.

Copy and paste it into sketchpad.

Code: Select all
/*
    RT : change type of new polygon
    F : create new polygon
    QWEASD : move selected polygons
    XC : move selector box
    Z : select a polygon
    VB : move selector circle
    G : select a vertex, create new link
*/
float face = [], link = [], stiffness = 0.2, metric = [1, 1, 1];
// face[i] = [numberOfEdges, positionVector, orientationVector1,Vector2,Vector3, isSelected]
// link[i] = [indexOfFace1,VertexInFace1, indexOfFace2,VertexInFace2]
int nNew = 3, fIndex = 0, fIndex2 = 0, vIndex1 = 0, vIndex2 = 0;
bool vSelected = false;
float sum = function(a, b) {
    return [a[0]+b[0], a[1]+b[1], a[2]+b[2]];
},
dif = function(a, b) {
    return [a[0]-b[0], a[1]-b[1], a[2]-b[2]];
},
scal = function(a, b) {
    return [a[0]*b, a[1]*b, a[2]*b];
},
dot = function(a, b) { // vector dot vector = scalar
    return metric[0]*a[0]*b[0] + metric[1]*a[1]*b[1] + metric[2]*a[2]*b[2];
},
wedge = function(a, b) { // vector wedge vector = bivector
    return [a[1]*b[2]-a[2]*b[1],
            a[2]*b[0]-a[0]*b[2],
            a[0]*b[1]-a[1]*b[0]];
},
dotB = function(a, b) { // vector dot bivector = vector
    return [metric[2]*a[2]*b[1] - metric[1]*a[1]*b[2],
            metric[0]*a[0]*b[2] - metric[2]*a[2]*b[0],
            metric[1]*a[1]*b[0] - metric[0]*a[0]*b[1]];
};
//append(face, [5, [0,0,0], [1,0,0],[0,1,0],[0,0,1], true]);
//append(face, [4, [0,0,2], [1,0,0],[0,0,1],[0,-1,0], false]);
//append(link, [0,1, 1,3]);
float ref = []; // reference polygon
for(int i = 2; i <= 12; i++) {
    float radius = 1/(2*sin(PI/i)), angle = 2*PI/i;
    ref[i] = [];
    for(int j = 0; j < i; j++) {
        ref[i][j] = [radius*cos(j*angle), radius*sin(j*angle), 0];
    }
}
bool keys = []; int turn = [];
void force = function() {
    float velocity = []; // linear and angular
    for(int i = 0; i < face.length; i++) {
        velocity[i] = [[0,0,0], [0,0,0]];
        if(face[i][5]){
            if(keys[68]) {
                int t = turn[68];
                if(t == 87) {
                    velocity[i][1] = sum(velocity[i][1], [0,0,-0.1]);
                } else if(t == 83) {
                    velocity[i][1] = sum(velocity[i][1], [0,0,0.1]);
                } else if(t == 69) {
                    velocity[i][1] = sum(velocity[i][1], [0,0.1,0]);
                } else if(t == 81) {
                    velocity[i][1] = sum(velocity[i][1], [0,-0.1,0]);
                } else {
                    velocity[i][0] = sum(velocity[i][0], [0.1,0,0]);
                }
            }
            if(keys[65]) {
                int t = turn[65];
                if(t == 87) {
                    velocity[i][1] = sum(velocity[i][1], [0,0,0.1]);
                } else if(t == 83) {
                    velocity[i][1] = sum(velocity[i][1], [0,0,-0.1]);
                } else if(t == 69) {
                    velocity[i][1] = sum(velocity[i][1], [0,-0.1,0]);
                } else if(t == 81) {
                    velocity[i][1] = sum(velocity[i][1], [0,0.1,0]);
                } else {
                    velocity[i][0] = sum(velocity[i][0], [-0.1,0,0]);
                }
            }
            if(keys[87]) {
                int t = turn[87];
                if(t == 68) {
                    velocity[i][1] = sum(velocity[i][1], [0,0,0.1]);
                } else if(t == 65) {
                    velocity[i][1] = sum(velocity[i][1], [0,0,-0.1]);
                } else if(t == 69) {
                    velocity[i][1] = sum(velocity[i][1], [-0.1,0,0]);
                } else if(t == 81) {
                    velocity[i][1] = sum(velocity[i][1], [0.1,0,0]);
                } else {
                    velocity[i][0] = sum(velocity[i][0], [0,0.1,0]);
                }
            }
            if(keys[83]) {
                int t = turn[83];
                if(t == 68) {
                    velocity[i][1] = sum(velocity[i][1], [0,0,-0.1]);
                } else if(t == 65) {
                    velocity[i][1] = sum(velocity[i][1], [0,0,0.1]);
                } else if(t == 69) {
                    velocity[i][1] = sum(velocity[i][1], [0.1,0,0]);
                } else if(t == 81) {
                    velocity[i][1] = sum(velocity[i][1], [-0.1,0,0]);
                } else {
                    velocity[i][0] = sum(velocity[i][0], [0,-0.1,0]);
                }
            }
            if(keys[69]) {
                int t = turn[69];
                if(t == 68) {
                    velocity[i][1] = sum(velocity[i][1], [0,-0.1,0]);
                } else if(t == 65) {
                    velocity[i][1] = sum(velocity[i][1], [0,0.1,0]);
                } else if(t == 87) {
                    velocity[i][1] = sum(velocity[i][1], [0.1,0,0]);
                } else if(t == 83) {
                    velocity[i][1] = sum(velocity[i][1], [-0.1,0,0]);
                } else {
                    velocity[i][0] = sum(velocity[i][0], [0,0,0.1]);
                }
            }
            if(keys[81]) {
                int t = turn[81];
                if(t == 68) {
                    velocity[i][1] = sum(velocity[i][1], [0,0.1,0]);
                } else if(t == 65) {
                    velocity[i][1] = sum(velocity[i][1], [0,-0.1,0]);
                } else if(t == 87) {
                    velocity[i][1] = sum(velocity[i][1], [-0.1,0,0]);
                } else if(t == 83) {
                    velocity[i][1] = sum(velocity[i][1], [0.1,0,0]);
                } else {
                    velocity[i][0] = sum(velocity[i][0], [0,0,-0.1]);
                }
            }
        }
    }
    for(int i = 0; i < link.length; i++) {
        int f1 = link[i][0], v1 = link[i][1],
            f2 = link[i][2], v2 = link[i][3];
        float refRadius1 = ref[face[f1][0]][v1],
              refRadius2 = ref[face[f2][0]][v2],
              radius1 = sum(scal(face[f1][2],refRadius1[0]), scal(face[f1][3],refRadius1[1])),
              radius2 = sum(scal(face[f2][2],refRadius2[0]), scal(face[f2][3],refRadius2[1])),
              pos1 = sum(face[f1][1], radius1),
              pos2 = sum(face[f2][1], radius2),
              posRel = dif(pos2, pos1),
              F = scal(posRel, stiffness),
              T1 = wedge(radius1, F),
              T2 = wedge(F, radius2);
        velocity[f1][0] = sum(velocity[f1][0], F);
        velocity[f2][0] = dif(velocity[f2][0], F);
        velocity[f1][1] = sum(velocity[f1][1], T1);
        velocity[f2][1] = sum(velocity[f2][1], T2);
    }
    for(int i = 0; i < face.length; i++) {
        face[i][1] = sum(face[i][1], velocity[i][0]);
        face[i][2] = sum(face[i][2], dotB(face[i][2], velocity[i][1]));
        face[i][3] = sum(face[i][3], dotB(face[i][3], velocity[i][1]));
        face[i][4] = sum(face[i][4], dotB(face[i][4], velocity[i][1]));
        float sq1 = dot(face[i][2],face[i][2]); // Gram-Schmidt
        face[i][3] = dotB(scal(face[i][2],sq1), wedge(face[i][2],face[i][3]));
        float sq2 = dot(face[i][3],face[i][3]);
        face[i][4] = dotB(scal(face[i][2],sq1), wedge(face[i][2],face[i][4]));
        face[i][4] = dotB(scal(face[i][3],sq2), wedge(face[i][3],face[i][4]));
        float sq3 = dot(face[i][4],face[i][4]);
        face[i][2] = scal(face[i][2], 1/sqrt(abs(sq1)));
        face[i][3] = scal(face[i][3], 1/sqrt(abs(sq2)));
        face[i][4] = scal(face[i][4], 1/sqrt(abs(sq3)));
    }
};
void display = function() {
    strokeWeight(1);
    stroke(0,255,255);
    for(var i = 0; i < link.length; i++) {
        int f1 = link[i][0], v1 = link[i][1],
            f2 = link[i][2], v2 = link[i][3];
        float refRadius1 = ref[face[f1][0]][v1],
              refRadius2 = ref[face[f2][0]][v2],
              radius1 = sum(scal(face[f1][2],refRadius1[0]), scal(face[f1][3],refRadius1[1])),
              radius2 = sum(scal(face[f2][2],refRadius2[0]), scal(face[f2][3],refRadius2[1])),
              pos1 = sum(face[f1][1], radius1),
              pos2 = sum(face[f2][1], radius2);
        if(pos1[0] < 4 && pos2[0] < 4) {
            line(200+50*pos1[0], 200-50*pos1[2], 200+50*pos2[0], 200-50*pos2[2]);
        }
        if(pos1[0] > -4 && pos1[1] > -4 && pos2[0] > -4 && pos2[1] > -4) {
            line(500+25*pos1[0], 100-25*pos1[1], 500+25*pos2[0], 100-25*pos2[1]);
            line(500+25*pos1[0], 300+25*pos1[1], 500+25*pos2[0], 300+25*pos2[1]);
        }
    }
    if(vSelected && face.length > 0) {
        float refRadius = ref[face[fIndex2][0]][vIndex2],
              radius = sum(scal(face[fIndex2][2],refRadius[0]), scal(face[fIndex2][3],refRadius[1])),
              pos = sum(face[fIndex2][1], radius);
        noStroke();
        fill(0,255,255,128);
        if(pos[0] < 4) {
            ellipse(200+50*pos[0], 200-50*pos[2], 20, 20);
        }
        if(pos[0] > -4 && pos[1] > -4) {
            ellipse(500+25*pos[0], 100-25*pos[1], 10, 10);
            ellipse(500+25*pos[0], 300+25*pos[1], 10, 10);
        }
    }
    for(var i = 0; i < face.length; i++) {
        float pos = [], normal = face[i][4];
        for(int j = 0; j < face[i][0]; j++) {
            float refRadius = ref[face[i][0]][j],
                  radius = sum(scal(face[i][2],refRadius[0]), scal(face[i][3],refRadius[1]));
            pos[j] = sum(face[i][1], radius);
        }
        bool inBox = true;
        for(int j = 0; j < face[i][0]; j++) {
            inBox = inBox && pos[j][0] < 4;
        }
        if(normal[1] < 0 && inBox) {
            if(face[i][5]) {
                strokeWeight(1);
                stroke(0);
            } else {
                noStroke();
            }
            fill(0,255,0,128);
            beginShape();
            for(int j = 0; j < face[i][0]; j++) {
                vertex(200+50*pos[j][0], 200-50*pos[j][2]);
            }
            endShape(CLOSE);
            strokeWeight(3);
            stroke(0,0,255);
            for(int j = 0; j < face[i][0]; j++) {
                point(200+50*pos[j][0], 200-50*pos[j][2]);
            }
        }
        inBox = true;
        for(int j = 0; j < face[i][0]; j++) {
            inBox = inBox && pos[j][0] > -4 && pos[j][1] > -4;
        }
        if(normal[2] > 0 && inBox) {
            if(face[i][5]) {
                strokeWeight(1);
                stroke(0);
            } else {
                noStroke();
            }
            fill(0,255,0,128);
            beginShape();
            for(int j = 0; j < face[i][0]; j++) {
                vertex(500+25*pos[j][0], 100-25*pos[j][1]);
            }
            endShape(CLOSE);
            strokeWeight(3);
            stroke(0,0,255);
            for(int j = 0; j < face[i][0]; j++) {
                point(500+25*pos[j][0], 100-25*pos[j][1]);
            }
        }
        if(normal[2] < 0 && inBox) {
            if(face[i][5]) {
                strokeWeight(1);
                stroke(0);
            } else {
                noStroke();
            }
            fill(0,255,0,128);
            beginShape();
            for(int j = 0; j < face[i][0]; j++) {
                vertex(500+25*pos[j][0], 300+25*pos[j][1]);
            }
            endShape(CLOSE);
            strokeWeight(3);
            stroke(0,0,255);
            for(int j = 0; j < face[i][0]; j++) {
                point(500+25*pos[j][0], 300+25*pos[j][1]);
            }
        }
    }
    if(face.length > 0) {
        float pos = [];
        for(int j = 0; j < face[fIndex][0]; j++) {
            float refRadius = ref[face[fIndex][0]][j],
                  radius = sum(scal(face[fIndex][2],refRadius[0]), scal(face[fIndex][3],refRadius[1]));
            pos[j] = sum(face[fIndex][1], radius);
        }
        strokeWeight(1);
        stroke(0);
        noFill();
        if(pos[vIndex1][0] < 4) {
            ellipse(200+50*pos[vIndex1][0], 200-50*pos[vIndex1][2], 10, 10);
        }
        if(pos[vIndex1][0] > -4 && pos[vIndex1][1] > -4) {
            ellipse(500+25*pos[vIndex1][0], 100-25*pos[vIndex1][1], 5, 5);
            ellipse(500+25*pos[vIndex1][0], 300+25*pos[vIndex1][1], 5, 5);
        }
        float selectBox = [400,400, 0,0];
        for(int j = 0; j < face[fIndex][0]; j++) {
            selectBox[0] = min(selectBox[0], 200+50*pos[j][0]);
            selectBox[1] = min(selectBox[1], 200-50*pos[j][2]);
            selectBox[2] = max(selectBox[2], 200+50*pos[j][0]);
            selectBox[3] = max(selectBox[3], 200-50*pos[j][2]);
        }
        rect(selectBox[0]-10,selectBox[1]-10, selectBox[2]-selectBox[0]+20,selectBox[3]-selectBox[1]+20);
        selectBox = [600,200, 400,0];
        for(int j = 0; j < face[fIndex][0]; j++) {
            selectBox[0] = min(selectBox[0], 500+25*pos[j][0]);
            selectBox[1] = min(selectBox[1], 100-25*pos[j][1]);
            selectBox[2] = max(selectBox[2], 500+25*pos[j][0]);
            selectBox[3] = max(selectBox[3], 100-25*pos[j][1]);
        }
        strokeWeight(1);
        stroke(0);
        noFill();
        rect(selectBox[0]-5,selectBox[1]-5, selectBox[2]-selectBox[0]+10,selectBox[3]-selectBox[1]+10);
        selectBox = [600,400, 400,200];
        for(int j = 0; j < face[fIndex][0]; j++) {
            selectBox[0] = min(selectBox[0], 500+25*pos[j][0]);
            selectBox[1] = min(selectBox[1], 300+25*pos[j][1]);
            selectBox[2] = max(selectBox[2], 500+25*pos[j][0]);
            selectBox[3] = max(selectBox[3], 300+25*pos[j][1]);
        }
        strokeWeight(1);
        stroke(0);
        noFill();
        rect(selectBox[0]-5,selectBox[1]-5, selectBox[2]-selectBox[0]+10,selectBox[3]-selectBox[1]+10);
    }
    noStroke();
    fill(192);
    rect(380,0, 40,400);
    rect(380,180, 220,40);
    fill(0);
    text("side view", 0,12);
    text("top view", 420,12);
    text("bottom view", 420,232);
    text(nNew +"-gon", 380,212);
};
void setup() {
    background(255);
    size(600, 400);
    smooth();
    frameRate(10);
}
void keyPressed() {
    keys[keyCode] = true;
    for(int i = 65; i <= 90; i++) {
        if(i != keyCode && keys[i] && !turn[i]) {
            turn[keyCode] = i;
        }
    }
    if(keyCode == 84) {
        nNew++;
        if(nNew > 12) {
            nNew = 2;
        }
    } else if(keyCode == 82) {
        nNew--;
        if(nNew < 2) {
            nNew = 12;
        }
    } else if(keyCode == 70) {
        append(face, [nNew, [0,0,0], [1,0,0],[0,1,0],[0,0,1], true]);
    } else if(keyCode == 67 && face.length > 0) {
        fIndex++;
        if(fIndex >= face.length) {
            fIndex-= face.length;
        }
        if(vIndex1 >= face[fIndex][0]) {
            vIndex1-= face[fIndex][0];
        }
    } else if(keyCode == 88 && face.length > 0) {
        fIndex--;
        if(fIndex < 0) {
            fIndex+= face.length;
        }
        if(vIndex1 >= face[fIndex][0]) {
            vIndex1-= face[fIndex][0];
        }
    } else if(keyCode == 90 && face.length > 0) {
        face[fIndex][5] = !face[fIndex][5];
    } else if(keyCode == 66 && face.length > 0) {
        vIndex1++;
        if(vIndex1 >= face[fIndex][0]) {
            vIndex1-= face[fIndex][0];
        }
    } else if(keyCode == 86 && face.length > 0) {
        vIndex1--;
        if(vIndex1 < 0) {
            vIndex1+= face[fIndex][0];
        }
    } else if(keyCode == 71 && face.length > 0) {
        if(vSelected) {
            append(link, [fIndex,vIndex1, fIndex2,vIndex2]);
            vSelected = false;
        } else {
            fIndex2 = fIndex;
            vIndex2 = vIndex1;
            vSelected = true;
        }
    }
}
void keyReleased() {
    keys[keyCode] = false;
    turn[keyCode] = 0;
}
void draw() {
    force();
    background(255);
    display();
}
mr_e_man
Dionian
 
Posts: 59
Joined: Tue Sep 18, 2018 4:10 am

Return to Programming

Who is online

Users browsing this forum: No registered users and 2 guests

cron