The Escher Stripes Project

by Arina Rivkin



Project description


Picture examples

User manual

Executables and source code




The works of the famous Dutch graphic artist M.C. Escher had become the great interest of many people working in Computer Graphics field. On his drawing Escher presents variety of graphical effects and illusions. The main challenge for Computer Graphics people is to create the models that look like so-called impossible structures on his drawings.

Project description:

This project concentrated on one of the Escher's works called "Rind". The goal was to take a general 3D computer model and create the stripe that envelops it, the same way the stripe encloses the head on the original picture.
The problem was solved by two different approaches, using two well known Computer Graphics techniques, Ray Tracing and Volumetric Texture Mapping. The algorithms for creating the stripe are presented in the next section.

The project was written using IRIT solid modeling system.


Two algorithms, that achieve the stripe effect, were offered and implemented in this project.

But first, a little bit of mathematics. The shape of the stripe resembles a helix. The helix with radius r and rotational axis  Z, can be described by the parametric curve c(t) = (r*cos(t), r*sin(t), t). Both methods are based on this representation.

Every application, that uses a volumetric texture mapping technique, goes through all the points on the object's surface and on each point applies a function. This function can make some manipulations on the point's color or on the normal of the surface in that point etc.

Here we assume that the model has a rotational axis. No other models were treated by this algorithm.

 In our application we define such a function to decide whether the point is lying on one of the stripe's boundaries or not. Like in the first algorithm, the user must define the rotational axis (we'll assume that Z is a rotational axis). The coordinates of the points on the lower stripe boundary must be (a*cos(t), a*sin(t), t). And similarly, the coordinates of the points on the upper stripe boundary must be          (a*cos(t), a*sin(t), t+Δ). Therefore, the mapping function checks the point's coordinates and if they meet one of the demands above, mark the point as one on the boundary. This way we collect the points on the stripe's boundaries. In this algorithm there is no way to triangulate the stripe in the same time that we searching for new points and also the points we find are not distributed uniformly on both stripe, that makes it harder to perform trivial triangulation, like in the first algorithm, by taking alternating points from upper and lower stripe one after another. Thus, here we make some estimations of distances between last point participating in triangulation and the new candidate point, to achieve optimal triangulation.

As one can see, the requirement for a point to have the (a*cos(t), a*sin(t), t) coordinates is just another way to demand a ray, that origin at (0, 0, t) and is directed at (cos(t), sin(t), 0),  intersect the surface at the given point. So, as it was said earlier, the two algorithms just approach the problem from the different views.

Once we created the stripe, we add some "noise" to it. The noise makes the stripe to look more like a texture stripe, i.e. more "wavy". The user can set the magnitude and the frequency of the noise.


EscherStripesRayIntr -i teapot1.itd -r y -w 0.2 -a 10 -p 0.4 -f 30 -c tpotCrvs.itd -o teapotStripe1.itd  


EscherStripesRayIntr  -i pawns.itd -w 0.04 -n 0.007 -a 3 -p 0.06 -f 10 -o pawnsStripe.itd


EscherStripesRayIntr -i teapot2.itd -r x  -n 0.0 -f 100 -s -o teapotStripe2.itd


EscherStripesVolTextureMap -i orange.itd -w 0.4 -n 0.07  -p 0.25 -f 100 -o orangeStripe.itd


EscherStripesVolTextureMap -i glass.itd -w 0.2 -n 0.08  -p 0.25 -f 70 -o glassStripe.itd

User Manual:

The applications are command line applications, so there are number of options that can be set by the user.

The possible options for both applications are:

[-i string] [-r "x" "y" "z"] [-w float] [-n double] [-p double] [-f integer] [-o string]

The additional three switches for the application that uses ray tracing are:

[-a integer] [-c string] [-s] 

Also, stripe width, stripe pitch and noise magnitude can be set separately for each object of the original model. The user can add these three attributes directly to the data file. The names of the attributes are [stripe_width ...], [stripe_pitch ...] and [stripe_noise ...]. The values of these attributes will be treated as RELATIVE values, i.e. the value that was set by the command line or default value will be multiplied by the attribute value for each object of the model, if that attribute appear in the data file.


Next are the compressed sources and executables: