# ShapeJS Developer Tutorials

## Reflection

Most objects we encounter have some form of symmetry. This means that we can build half of what we want, or even less, if we can then simply reflect it. In this Tutorial we will learn how to use ShapeJS's built in symmetry functions in order to modify data sources.

### 1. Planar Reflection

Let's start by modeling the beginnings of a toy car.

```function main(args) {
var r = 15*MM;
var sphere = new Torus(r, r/5);
var box = new Box(0,0,0, 1.5*r,1.5*r, 1.5*r);

var s = 26*MM;
return new Scene(shape,new Bounds(-s,s,-s,s,-s,s));
}
```
###### Try it!

Now, we could repeat all the same operations, creations, and so forth on the other side. And then do both to make the rear end of the car. What we would be doing is manually creating reflections. But there is a much simpler way: using planar reflect. However, we need multiple reflections: once over the Z axis, and once over the X axis. Fortunately, we can combine multiple planar reflections into a single transformation. We'll also get another shot at creating a function. By doing this, we can create the whole car while only really modeling a fourth of it. Everything we are doing here should be familiar, except for this ReflectionSymmetry operation.

By using it we can avoid having to do any more modeling. Instead, we just create two planes, one along the X axis, one along the Z. We then apply this like any other transformation in order to get a more complete vehicle, rather than a single seater circle driver.

```function main(args) {
var r = 15*MM;
var sphere = new Torus(r, r/5);
var box = new Box(0,0,0, 1.5*r,1.5*r, 1.5*r);

var s = 26*MM;
return new Scene(shape,new Bounds(-s,s,-s,s,-s,s));
}
```
###### Try it!

(Note: for a simpler reflections that only require a single transform, rather than having to set up an array, try using PlaneReflection.)

### 2. Circular Reflection

Beyond the basic planar reflection, we can also reflect a data source on a sphere. You can find a bit more technical explanation by reading about the Riemann sphere. Essentially what this will do is reflect your object on a spherical surface

Meanwhile, we have a fairly boring car. Let's take it and make it into the Fractalmobile by adding a spherical reflection.

```function quadSymmetry(){
var reflection_plane = new Array();
var count = 0;

reflection_plane[count++] = new ReflectionSymmetry.getPlane(new Vector3d(0,0,-1),0);
reflection_plane[count++] = new ReflectionSymmetry.getPlane(new Vector3d(-1,0,0),0);
reflection_plane[count++] = new ReflectionSymmetry.getSphere(new Vector3d(10*MM, 0, 0), -9*MM);
return new ReflectionSymmetry(reflection_plane);
}

function main(args) {
var chassisbase = new Box (2*MM, 0, 5*MM, 4*MM, 2*MM, 10*MM);
var chassisangle = new Plane (new Vector3d(4*MM, 1*MM, 10*MM), new Vector3d(3*MM, -1*MM, 10*MM), new Vector3d(4*MM, 1*MM, 10*MM));
var chassis = new Intersection(chassisbase, chassisangle);
var topbase = new Box (1.5*MM, 2*MM, 2*MM, 3*MM, 2*MM, 4*MM);
var topangle = new Plane (new Vector3d(0, 1*MM, 4*MM), new Vector3d(3*MM, 1*MM, 4*MM), new Vector3d(3*MM, 3*MM, 2*MM));
var top = new Intersection(topbase, topangle);
var bumperbase = new Box (1.8*MM, -0.5*MM, 10.25*MM, 4*MM, 1*MM, 0.5*MM);
var wheelbase = new Cylinder (new Vector3d(3.5*MM, -0.8*MM, 8*MM),new Vector3d(4.5*MM, -0.8*MM, 8*MM), 1*MM);
var fenderbase = new Cylinder (new Vector3d(4*MM, -0.8*MM, 8*MM),new Vector3d(4.2*MM, -0.8*MM, 8*MM), 1.5*MM, 1.1*MM);
var fender = new Subtraction(fenderbase, new Cylinder(new Vector3d(0, -1*MM, 0), new Vector3d(0, -1, 0), 1));
//
var car = new Union();