I'd like to manipulate a UVSphere using mathematical equations

After reading Choma's inspiration book Morphing and looking at his web based tool http://www.morphingbook.com/tool.html, I'm trying to build my own version that creates surfaces. I'm having problems figuring out how to input mathematical formulas though.

The example below has a few test sliders to manipulate common values, however I'd like to able to use text-based mathematical inputs. I can't see how toggles and sliders can replace mathematical combinations of sin, cos, phi, theta, exponents and their relationships.

The beauty of the web based tool is that bad math will only result in no-sketch. I'm not sure how to even do this in processing's java mode. Can anyone help with this? Thanks.

(as a side note, the UV sphere my code generates has problems with the QUAD_STRIP. try dragging down the transparency to zero and you'll see the weirdness.)

import controlP5.*;
import peasy.test.*;
import peasy.org.apache.commons.math.*;
import peasy.*;
import peasy.org.apache.commons.math.geometry.*;
PeasyCam camera;
ControlP5 cp5;
Slider uMinSlider;
Slider uMaxSlider;
Slider vMinSlider;
Slider vMaxSlider;

/* 
 phi = u
 theta = v
 */

float stepLat, stepLon, radius, phi, theta, u, v;
float uMin, uMax, vMin, vMax, u2Mult, v2Mult, transparency;
float xVMult, yVMult, zVMult, xUMult, yUMult, zUMult; 
int myColor = color(255, 0, 0);

void setup() {
  size(1000, 1000, OPENGL);
  smooth(8);
  strokeWeight(1);
  //noFill();  
  radius = width/20;

  camera = new PeasyCam(this, 0, 0, 0, width * 0.2);
  cp5 = new ControlP5(this);
  uMinSlider = cp5.addSlider("uMin");
  uMinSlider.setPosition(40, 40).setSize(200, 20).setRange(0.0, 2.0).setValue(0.0);
  uMaxSlider = cp5.addSlider("uMax");
  uMaxSlider.setPosition(40, 60).setSize(200, 20).setRange(0.0, 2.0).setValue(2.0);
  vMinSlider = cp5.addSlider("vMin");
  vMinSlider.setPosition(40, 80).setSize(200, 20).setRange(0.0, 2.0).setValue(0.0);
  vMaxSlider = cp5.addSlider("vMax");
  vMaxSlider.setPosition(40, 100).setSize(200, 20).setRange(0.0, 2.0).setValue(2.0);
  vMaxSlider = cp5.addSlider("stepLat");
  vMaxSlider.setPosition(40, 120).setSize(200, 20).setRange(1, 25).setValue(5);
  vMaxSlider = cp5.addSlider("stepLon");
  vMaxSlider.setPosition(40, 140).setSize(200, 20).setRange(1, 25).setValue(5);
  vMaxSlider = cp5.addSlider("v2Mult");
  vMaxSlider.setPosition(40, 160).setSize(200, 20).setRange(0, 50).setValue(1);
  vMaxSlider = cp5.addSlider("u2Mult");
  vMaxSlider.setPosition(40, 180).setSize(200, 20).setRange(0, 50).setValue(0);  
  vMaxSlider = cp5.addSlider("transparency");
  vMaxSlider.setPosition(40, 200).setSize(200, 20).setRange(0, 255).setValue(255);

  vMaxSlider = cp5.addSlider("xVMult");
  vMaxSlider.setPosition(width - 400, 40).setSize(100, 20).setRange(-5, 5).setValue(1);
  vMaxSlider = cp5.addSlider("xUMult");
  vMaxSlider.setPosition(width - 200, 40).setSize(100, 20).setRange(-5, 5).setValue(1);

  vMaxSlider = cp5.addSlider("yVMult");
  vMaxSlider.setPosition(width - 400, 60).setSize(100, 20).setRange(-5, 5).setValue(1);
  vMaxSlider = cp5.addSlider("yUMult");
  vMaxSlider.setPosition(width - 200, 60).setSize(100, 20).setRange(-5, 5).setValue(1);

  vMaxSlider = cp5.addSlider("zVMult");
  vMaxSlider.setPosition(width - 200, 80).setSize(100, 20).setRange(-5, 5).setValue(1);
  //vMaxSlider = cp5.addSlider("zUMult");
  //vMaxSlider.setPosition(width - 200, 140).setSize(100, 20).setRange(-5, 5).setValue(1);

  cp5.addTextfield("xValue").setPosition(width - 400, 120).setSize(300, 20).setAutoClear(false);
  cp5.addBang("Submit").setPosition(width - 400, 160).setSize(40, 20);  

  cp5.setAutoDraw(false);
}

void draw() {
  background(155);
  gui();
  stroke(255, 200, 200);
  fill(255, 155, 155, transparency);
  lights();
  //camcam.draw();

  for (float i = (degrees (vMin * PI)); i <= (degrees(vMax * PI)); i += stepLon) {
    beginShape(QUAD_STRIP);
    for (float j = (degrees (uMin * PI)); j <= (degrees(uMax * PI)); j += stepLat) {
      float v = i * ((2 * PI) / (degrees(2.0 * PI)));
      float u = j * ((2 * PI) / (degrees(2.0 * PI)));
      float v2 = (i + (stepLon * v2Mult)) * ((2 * PI)  / (degrees(2.0 * PI)));
      //u2Mult = 0 for a UVSPHERE
      float u2 = (j + (stepLat * u2Mult)) * ((2 * PI) / (degrees(2.0 * PI)));
      //THESE DO OTHER COOL THINGS!
      //float v2 = (i += stepLon) * ((2 * PI)  / (degrees(2.0 * PI)));
      //float u2 = (j += stepLat) * ((2 * PI) / (degrees(2.0 * PI)));
      float x2 = radius * (sin(v * xVMult) * cos(u * xUMult));
      float y2 = radius * (sin(v * yVMult) * sin(u * yUMult));
      float z2 = radius * (cos(v * zVMult));  
      float x3 = radius * (sin(v2 * xVMult) * cos(u2 * xUMult));
      float y3 = radius * (sin(v2 * yVMult) * sin(u2 * yUMult));
      float z3 = radius * (cos(v2 * zVMult));  
      vertex(x2, y2, z2);
      vertex(x3, y3, z3);
    }
    endShape();
  }
}

void gui() {
  camera.beginHUD();
  hint(ENABLE_DEPTH_TEST);
  cp5.draw();
  hint(DISABLE_DEPTH_TEST);
  camera.endHUD();
}
Sign In or Register to comment.