ShapeJS Developer Tutorials

Parameters and Functions

While there are some properties that can be changed by what you decide to put into individual functions, others are not immediately visible. Much like the blending we learned about earlier, these are parameters which may not be obviously and immediately available to you within the functions themselves. In order to modify them, we need to learn about parameters. In this tutorial we will start learning about how to use parameters in order to add more control of data sources and transformations.

1. Parameters

For a lot of functions, particularly primitives, we have an option for putting in different sets of variables. But there are other variables that we could potentially control not directly available within the function itself. You can set these parameters in a few different ways. Let's take a look at this with a parameter we have already seen, blend.

 intersection.setBlend(0.5*MM);

This could also be set by

 intersection.set("blend", 0.5*MM);

or even by

 intersection.getParam("blend").setValue(0.5*MM)

But why? By doing this we have a larger degree of control over every function. While the defaults for these parameters are generally perfectly good, you may need to change them from time to time. Some, like Blend or Transform (both of which we have already learned) have no effect by default--they are set to zero.

However, there are many more parameters that can be set, for all kinds of functions. These allow you a lot more control over what happens, instead of relying on defaults and hoping that they work. The parameters available to each function are listed in the documentation.

2. Functions

If we end up performing similar operations over and over again, or simply want to separate a part of the process, we can optimize by putting that operation into a function. So far we have only really used the functions already set up in ShapeJS. But we can expand that in order to make things a lot easier for ourselves.

We've ended up with a lot of redundant code. While the code works fine this way, it is going to be difficult to change, since we will have to go back through and adjust each one if we want to make any edits. However, if we put it all into a single function...

function twister(){
  var ct = new CompositeTransform();
  ct.add(new Rotation(new Vector3d(1,0,0), Math.PI/2));
  ct.add(new Twist(0.5));
  ct.add(new Rotation(new Vector3d(1,0,0), -Math.PI/2));
  return ct;}

function main(args) {
  var top = new Box (0, 11*MM, 0, 24*MM, 2*MM, 24*MM);
  var bottom = new Box (0, -11*MM, 0, 24*MM, 2*MM, 24*MM);
  var s1 = new Box(11*MM, 0, 11*MM, 2*MM, 24*MM, 2*MM);
  s1.setTransform(twister());
  var s2 = new Box(-11*MM, 0, 11*MM, 2*MM, 24*MM, 2*MM);
  s2.setTransform(twister());
  var s3 = new Box(11*MM, 0, -11*MM, 2*MM, 24*MM, 2*MM);
  s3.setTransform(twister());
  var s4 = new Box(-11*MM, 0, -11*MM, 2*MM, 24*MM, 2*MM);
  s4.setTransform(twister());

  var board = new Union();
  board.add(top);
  board.add(bottom);
  board.add(s1);
  board.add(s2);
  board.add(s3);
  board.add(s4);

  var s = 15*MM;
  return new Scene(board,new Bounds(-s,s,-s,s,-s,s));
}

Not only is this a lot cleaner, it's also a lot easier to follow. If we want to make changes, we can just adjust the function itself. But what if we wanted each support to twist differently? To do so, we just need to put in arguments, and we will be able to .

function twister(tf){
  var ct = new CompositeTransform();
  ct.add(new Rotation(new Vector3d(1,0,0), Math.PI/2));
  ct.add(new Twist(tf));
  ct.add(new Rotation(new Vector3d(1,0,0), -Math.PI/2));
  return ct;
}

function main(args) {
  var top = new Box (0, 11*MM, 0, 24*MM, 2*MM, 24*MM);
  var bottom = new Box (0, -11*MM, 0, 24*MM, 2*MM, 24*MM);
  var s1 = new Box(11*MM, 0, 11*MM, 2*MM, 24*MM, 2*MM);
  s1.setTransform(twister(0.5));
  var s2 = new Box(-11*MM, 0, 11*MM, 2*MM, 24*MM, 2*MM);
  s2.setTransform(twister(0.75));
  var s3 = new Box(11*MM, 0, -11*MM, 2*MM, 24*MM, 2*MM);
  s3.setTransform(twister(1));
  var s4 = new Box(-11*MM, 0, -11*MM, 2*MM, 24*MM, 2*MM);
  s4.setTransform(twister(1.25));

  var board = new Union();
  board.add(top);
  board.add(bottom);
  board.add(s1);
  board.add(s2);
  board.add(s3);
  board.add(s4);

  var s = 15*MM;
  return new Scene(board,new Bounds(-s,s,-s,s,-s,s));
}

By using functions we can create commands with varying levels of automation. By doing so, we can greatly simplify our script, without losing the wide range of options ShapeJS provides. For more complicated and repetitive a scene is, the more useful functions will be to keep everything straight.