# Iso-Holes

### Iso Holes

An alternative approach to faster holes is to use an isosurface.

Isosurfaces can often be slower than CSG, but in this case the CSG is so slow that an isosurface can be considerably faster. This image took 4 minutes 14 seconds to render on my machine. Because the isosurface is a single object, the speed doesn't change very much when the number of holes becomes large.

Here's the complete code that I used for the above image

```
#include "functions.inc"

#declare D=35;    // controls the density of the holes
// larger value gives more holes
#declare S = 0.1; // Controls the size of the holes
// larger value gives smaller holes

#declare R1=2;    // Radius of outer cylinder
#declare R2=1.6;  // Radius of inner cylinder
#declare H=4;     // Height of the cylinder

isosurface {
function {
max (                            // intersection
(f_leopard(D*R1*f_th(x,y,z),0,D*y) -S),   // of the holes
max (                         // with intersection
(x*x + z*z - R1*R1),           // the of outer cylinder
(-x*x - z*z + R2*R2)           // with the inner cylinder inverted
)
)
}
contained_by{box {-<R1,H/2,R1>,<R1,H/2,R1>}}
pigment {rgb .9}
finish {phong 0.5 phong_size 10}
}

camera { location  <-8, 4, 0> look_at <0, 0, 0> angle 35}

sky_sphere { pigment {
function{abs(y)}
color_map { [0.0 color blue 0.6] [1.0 color rgb 1] }
}
}

light_source { <-20,50,-5> colour rgb 1}
```

### Step by step

I started with a leopard pattern f_leopard(x,y,z). That gives a pattern of spheres in 3d space. I then substituted 0 for the z parameter f_leopard(x,y,0) which stretches the spheres out in the z direction so that they become cylinders.

The next job was to wrap the cylinders around the y axis, so that they radiate outwards. I achieved this by substituting longitude (Theta) for the x parameter f_leopard(f_th(x,y,z),y,0). Then, by making the function negative, I turned it into a set of cylindrical holes.

It's possible to perform intersection and difference operations of this isosurface with CSG cylinders, like this

```intersection {
isosurface {
function {
f_leopard(D*2*f_th(x,y,z),D*y,0) - 0.1
}
contained_by{box {-<2,2,2>,<2,2,2>}}
max_trace 6
}
difference {
cylinder {<0,-2,0>,<0,2,0>,2}
cylinder {<0,-2.1,0>,<0,2.1,0>,1.6}
}
}```
But this requires the application of the max_trace feature, which reduces the speed. So I then used the max operation to perform the intersection and difference operations.

The first of the next pair of images was created with CSG cylinder differences with max_trace 6 which turns out to be not quite enough, and there's some drop out on the far side. The second image of the pair was created with isosurface max operations and ran about three times faster.

### Variations

Instead of the leopard pattern, I could have used any repeating pattern, such as f_hexagon or created my own repeating pattern using repeat warps. The boxed pattern with repeat warps needs a much higher max_gradient and runs rather slowly.

For the spheres, the y parameter was replaced by the lattitude, Phi f_ph()

To have lines of holes tilted at a different angle I could substitute cos(A)*x +sin(A)*z for x and cos(A)*z -sin(A)*x for z. When combined with the other substitutions, that comes out like

```  f_leopard(D*(R1*f_th(x,y,z)*cos(A)+y*sin(A)),
0,
D*(y*cos(A)-R1*f_th(x,y,z)*sin(A)))
```

### Isosurfaces

If you're not familiar with some of the isosurface techniques used here, then you can find out more in my Isosurface Tutorial.

## Other Tricks

Holes Tutorial Part 1
Holes Tutorial Part 3: Transparent Holes (Bubbles)
Holes Tutorial Part 4: Blob-Holes

Back to Mike's Homepage