The following source code will create a truncated cube with the P3D renderer using beginShape()…endShape() with multiple vertices. Since it is difficult to add components to a GLWindow a separate JFrame controller window with Swing components was used. Two sliders provide alteration of cube size and crop length. Exploration with various settings result in interesting outputs. Cube rotation is achieved by click dragging the mouse in the main window. The control window is not closable; the app may be quit by closing the main window or hitting the ‘Quit’ button in the controller window. Using ‘Cmd-Q’ on a Mac will cause the runtime to hang due to thread destruction. This demo was developed on MacOS and has not been tested on other platforms.
Source code:
// LT = left top : RT = right top : RB = right bottom : LB = left bottom
import javax.swing.*;
import javax.swing.event.*;
float rotx = PI/4;
float roty = PI/4;
int s = 150;
int crop = s/2;
void buildControllerWnd() {
JFrame frame = new JFrame("Controller Wnd");
frame.setLayout(null);
frame.setBounds(50, 100, 300, 270);
// ====== Info Label ======= //
JLabel infoLabel = new JLabel("<html>Click on main window to select it, then click and drag mouse to rotate cube.</html>");
infoLabel.setBounds(30, 5, 250, 48);
// ====== Size Label ======= //
JLabel sizeLabel = new JLabel("Size");
sizeLabel.setBounds(30, 55, 80, 24);
// ====== Size Value ======= //
JLabel sValue = new JLabel();
sValue.setHorizontalAlignment(JLabel.CENTER);
sValue.setBounds(220, 75, 50, 24);
sValue.setText(Integer.toString(s));
// ====== Size Slider ======= //
JSlider sizeSlider = new JSlider(JSlider.HORIZONTAL, 0, 250, 150);
sizeSlider.setBounds(30, 75, 200, 24);
sizeSlider.addChangeListener(new ChangeListener() {
void stateChanged(ChangeEvent changeEvent) {
s = sizeSlider.getValue();
sValue.setText(Integer.toString(sizeSlider.getValue()));
}
}
);
// ======== Crop Label ======== //
JLabel cropLabel = new JLabel("Crop");
cropLabel.setBounds(30, 100, 80, 24);
// ======== Crop Value ======== //
JLabel cropValue = new JLabel();
cropValue.setHorizontalAlignment(JLabel.CENTER);
cropValue.setBounds(220, 120, 50, 24);
cropValue.setText(Integer.toString(crop));
// ======== Crop Slider ======= //
JSlider cropSlider = new JSlider(JSlider.HORIZONTAL, 0, 250, 75);
cropSlider.setBounds(30, 120, 200, 24);
cropSlider.addChangeListener(new ChangeListener() {
void stateChanged(ChangeEvent changeEvent) {
crop = cropSlider.getValue();
cropValue.setText(Integer.toString(cropSlider.getValue()));
}
}
);
// ====== Quit Label ======= //
JLabel quitLabel = new JLabel("<html>Close main window to quit the app or use Quit button below. Do not use cmd-Q (will hang runtime).</html>");
quitLabel.setBounds(30, 155, 250, 48);
// ====== Quit Button ====== //
JButton quitBtn = new JButton("Quit");
quitBtn.setBounds(190, 210, 80, 24);
quitBtn.addActionListener( e -> {
exit();
}
);
frame.add(infoLabel);
frame.add(sizeLabel);
frame.add(sValue);
frame.add(sizeSlider);
frame.add(cropLabel);
frame.add(cropValue);
frame.add(cropSlider);
frame.add(quitLabel);
frame.add(quitBtn);
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
frame.setVisible(true);
}
void setup() {
size( 800, 800, P3D );
surface.setTitle("Truncated Cube");
strokeWeight(4);
javax.swing.SwingUtilities.invokeLater(()-> {
buildControllerWnd(); // Build components on EventDispatchThread
}
);
}
void draw() {
background(128);
translate(width/2.0, height/2.0, -100);
rotateX(rotx);
rotateY(roty);
// ============ 6 Faces =========== //
// Front face
beginShape();
fill(255, 0, 0); // Red
vertex(-s, -s+crop, s); // LT lower crop * -> Front LT Triangle
vertex(-s+crop, -s, s); // LT upper crop * -> Front LT Triangle
vertex( s-crop, -s, s); // RT upper crop * -> Front RT Triangle
vertex( s, -s+crop, s); // RT lower crop * -> Front RT Triangle
vertex( s, s-crop, s); // RB upper crop * -> Front RB Triangle
vertex( s-crop, s, s); // RB lower crop * -> Front RB Triangle
vertex(-s+crop, s, s); // LB lower crop * -> Front LB Triangle
vertex(-s, s-crop, s); // LB upper crop * -> Front LB Triangle
endShape();
// Back face
beginShape();
fill(255, 255, 0); // Yellow
vertex( s, -s+crop, -s); // LT lower crop * -> Back LT Triangle
vertex( s-crop, -s, -s); // LT upper crop * -> Back LT Triangle
vertex(-s+crop, -s, -s); // RT upper crop * -> Back RT Triangle
vertex(-s, -s+crop, -s); // RT lower crop * -> Back RT Triangle
vertex(-s, s-crop, -s); // RB upper crop * -> Back RB Triangle
vertex(-s+crop, s, -s); // RB lower crop * -> Back RB Triangle
vertex( s-crop, s, -s); // LB lower crop * -> Back LB Triangle
vertex( s, s-crop, -s); // LB upper crop * -> Back LB Triangle
endShape();
// Bottom face
beginShape();
fill(255, 0, 255); // Magenta
vertex(-s, s, s-crop); // LT lower crop
vertex(-s+crop, s, s); // LT upper crop
vertex( s-crop, s, s); // RT upper crop
vertex( s, s, s-crop); // RT lower crop
vertex( s, s, -s+crop); // RB upper crop
vertex( s-crop, s, -s); // RB lower crop
vertex(-s+crop, s, -s); // LB lower crop
vertex(-s, s, -s+crop); // LB upper crop
endShape();
// Top face
beginShape();
fill(0, 255, 0); // Green
vertex(-s, -s, -s+crop); // LT lower crop
vertex(-s+crop, -s, -s); // LT upper crop
vertex( s-crop, -s, -s); // RT upper crop
vertex( s, -s, -s+crop); // RT lower crop
vertex( s, -s, s-crop); // RB upper crop
vertex( s-crop, -s, s); // RB lower crop
vertex(-s+crop, -s, s); // LB lower crop
vertex(-s, -s, s-crop); // LB upper crop
endShape();
// Right face
beginShape();
fill(0, 0, 255); // Blue
vertex( s, -s+crop, s); // LT lower crop
vertex( s, -s, s-crop); // LT upper crop * -> Front RT Triangle
vertex( s, -s, -s+crop); // RT upper crop * -> Back LT Triangle
vertex( s, -s+crop, -s); // RT lower crop
vertex( s, s-crop, -s); // RB upper crop
vertex( s, s, -s+crop); // RB lower crop * -> Back LB Triangle
vertex( s, s, s-crop); // LB lower crop * -> Front RB Triangle
vertex( s, s-crop, s); // LB upper crop
endShape();
// Left face
beginShape();
fill(0, 255, 255); // Turquoise
vertex(-s, -s+crop, -s); // LT lower crop
vertex(-s, -s, -s+crop); // LT upper crop * -> Back RT Triangle
vertex(-s, -s, s-crop); // RT upper crop * -> Front LT Triangle
vertex(-s, -s+crop, s); // RT lower crop
vertex(-s, s-crop, s); // RB upper crop
vertex(-s, s, s-crop); // RB lower crop * -> Front LB Triangle
vertex(-s, s, -s+crop); // LB lower crop * -> Back RB Triangle
vertex(-s, s-crop, -s); // LB upper crop
endShape();
// ========== 8 Triangles =========== //
beginShape(); // Front face LT triangle
fill(255); // White
vertex(-s, -s+crop, s); // Front LT lower crop * -> LT Triangle
vertex(-s+crop, -s, s); // Front LT upper crop * -> LT Triangle
vertex(-s, -s, s-crop); // Left RT upper crop * -> LT Triangle
endShape();
beginShape(); // Front face RT triangle
fill(255); // White
vertex( s-crop, -s, s); // Front RT upper crop * -> RT Triangle
vertex( s, -s+crop, s); // Front RT lower crop * -> RT Triangle
vertex( s, -s, s-crop); // Right LT upper crop * -> RT Triangle
endShape();
beginShape(); // Front face RB triangle
fill(255); // White
vertex( s, s-crop, s); // Front RB upper crop * -> RB Triangle
vertex( s-crop, s, s); // Front RB lower crop * -> RB Triangle
vertex( s, s, s-crop); // Right LB lower crop * -> RB Triangle
endShape();
beginShape(); // Front face LB triangle
fill(255); // White
vertex(-s+crop, s, s); // Front LB lower crop * -> LB Triangle
vertex(-s, s-crop, s); // Front LB upper crop * -> LB Triangle
vertex(-s, s, s-crop); // Left RB lower crop * -> LB Triangle
endShape();
beginShape(); // Back face LT triangle
fill(255); // White
vertex( s, -s+crop, -s); // Back LT lower crop * -> LT Triangle
vertex( s-crop, -s, -s); // Back LT upper crop * -> LT Triangle
vertex( s, -s, -s+crop); // Left RT upper crop * -> LT Triangle
endShape();
beginShape(); // Back face RT triangle
fill(255); // White
vertex(-s+crop, -s, -s); // Back RT upper crop * -> RT Triangle
vertex(-s, -s+crop, -s); // Back RT lower crop * -> RT Triangle
vertex(-s, -s, -s+crop); // Right LT upper crop * -> RT Triangle
endShape();
beginShape(); // Back face RB triangle
fill(255); // White
vertex(-s, s-crop, -s); // Back RB upper crop * -> RB Triangle
vertex(-s+crop, s, -s); // Back RB lower crop * -> RB Triangle
vertex(-s, s, -s+crop); // Left LB lower crop * -> RB Triangle
endShape();
beginShape(); // Back face LB triangle
fill(255); // White
vertex( s-crop, s, -s); // Back LB lower crop * -> LB Triangle
vertex( s, s-crop, -s); // Back LB upper crop * -> LB Triangle
vertex( s, s, -s+crop); // Right RB lower crop * -> LB Triangle
endShape();
}
void mouseDragged() {
float rate = 0.01;
rotx += (pmouseY-mouseY) * rate;
roty += (mouseX-pmouseX) * rate;
}
Normal Output:
Interesting Output:

