Shapes3D Change measurements of Box

I am currently working on a visualisation, where I have several Box Objects from the Shapes3D library which I want to animate. I want to change the height of the Boxes over a period of time using the lerp() function specifically. However, after looking through the documentation of Shapes3D as well as several older forum posts, I cant find any method/function which would allow me to change the height of the object, even though I saw mentions of a setSize() method in older forum posts. Said method seems to no longer exist though…
Ist there any other way to change the size of Box objects?
Thanks!

2 Likes

Welcome to the forum :grinning:

I can’t remember ever providing a method to resize the shapes in this library. When a shape is created it has to calculate and store all the vertices and surface normals so the shape can be rendered. Some of the more complex geometries have hundreds of vertices so it is impractical to recalculate them every frame to provide animation.

Yes :smiley:

Fortunately it is possible for users to extend the Shapes3D library, thereby adding their own functionality. To do this the user must create their own class to extend a library class.

The following sketch has two tabs, the first tab contains the main sketch code which I have adapted from one of the library examples. The second tab contains the code for a new class called ResizeableBox that extends the library class Box. Note the name of this tab MUST be Resizeable.java otherwise this is not going to work.

Main sketch code

/**
 * ===============================================
 * Simple resizeable box with shape picking
 * ===============================================
 *
 *    A Shapes3D library extension example
 *    created by Peter Lager 2024
 */

import shapes3d.*;
import shapes3d.contour.*;
import shapes3d.org.apache.commons.math.*;
import shapes3d.org.apache.commons.math.geometry.*;
import shapes3d.path.*;
import shapes3d.utils.*;

float ax, ay, az;
String s = "";

ResizeableBox shape0;
Shape3D shape1;

float theta = 0, deltaTheta = 0.02;
int w = 65, h = 200, d = 40;

void setup() {
  size(300, 300, P3D);
  cursor(CROSS);
  shape0 = new ResizeableBox(w, h, d);
  shape1 = new Ellipsoid(200, 200, 200, 8, 8);
  shape1.drawMode(S3D.WIRE).strokeWeight(1.2).stroke(color(255, 100, 100));
}

void draw() {
  theta += deltaTheta;
  shape0.resize(w, h*(1 + 0.7 * sin(theta)), d);
  background(0);
  push();
  // Move the world view coordinates [0,0,0]
  // to the centre of the display.
  translate(width/2, height/2, -200);
  // The next few lines rotate the graphics
  // context so we view the shape from dfiierent
  // angles making it appear to be tumbling.
  ax += 0.0063;
  ay += 0.0123;
  az += 0.0099;
  rotateX(ax);
  rotateY(ay);
  rotateZ(az);

  // Render the shape on the main display area
  shape0.draw(getGraphics());
  shape1.draw(getGraphics());

  pop();
  // Display a status bar and show the results from the
  // last shape pick operation (see mouseClicked method)
  fill(200, 255, 200);
  textAlign(CENTER, CENTER);
  textSize(16);
  text(s, 0, height-26, width, 26);
}

void mouseClicked() {
  // If te mouse is clicked see if the cursor is over a shape
  // if so show details of the shape and shape part clicked on
  Picked p = Shape3D.pick(this, getGraphics(), mouseX, mouseY);
  if (p != null) {
    s = p.shape.tag + "  part no. "  + p.part + " picked";
  } else {
    s = "Missed";
  }
}

ResizeableBox.java

// This MUST be in a separate tab called "ResizeableBox.java"

import processing.core.PVector;
import shapes3d.*;
import shapes3d.contour.*;
import shapes3d.org.apache.commons.math.*;
import shapes3d.org.apache.commons.math.geometry.*;
import shapes3d.path.*;
import shapes3d.utils.*;

/*
 * A regular axis aligned 3D box shape with 6 sides that can have
 * different visual attributes. 
 * 
 * The width, height and depth can be resized at runtime
 *
 * @author Peter Lager (2024)
 *
 */
public class ResizeableBox extends Box {

  /**
   * Create a box of given size.
   *
   * @param w width (x axis)
   * @param h height (y axis)
   * @param d depth (z axis)
   */
  public ResizeableBox(float w, float h, float d) {
    this(w, h, d, null);
  }

  /**
   * Create a box of given size and orientation.
   *
   * @param w width (x axis)
   * @param h height (y axis)
   * @param d depth (z axis)
   * @param orientation the orientation to use
   */
  public ResizeableBox(float w, float h, float d, Orientation orientation) {
    super(w, h, d, orientation);
  }

  /**
   * Resize the box
   *
   * @param nw width (x axis)
   * @param nh height (y axis)
   * @param nd depth (z axis)
   */
  public void resize(float nw, float nh, float nd) {
    this.w = nw;
    this.h = nh;
    this.d = nd;
    calcShape();
    makeParts();
    releaseMemory();
  }

  public ResizeableBox getThis() {
    return this;
  }
}
3 Likes