Name: Will Bolden
Login ID: wbolden
Date: 10/30/2016
High Level Description (what was implemented, what was not, any special features - Last Point):
- SORs can be loaded from file or created from polylines. Loaded and generated SORs can be displayed with flat shading, smooth shading, specular highlights, and normals can be toggled on and off. Ambient light with color [0, 0, 0.2] is applied to the scene. Slider to change value of alpha (glossiness), default 1 as specified. Cube and line can be clicked to toggle the point and directional light sources on and off. Only the directional light has a specular component. Can toggle between perspective and orthographic projection. Click and take appropriate actions to transform the selected SOR. Click on the background to transform the Camera. SOR objects are textured
User Guide:
- Draw a polyline to create the SOR, click the save button to save the SOR with a speicified filename
- Click on the load SOR button to load an existing SOR
Camera Controls:
Select the background and then...
- Middleclick and drag up or down to move the camera in or out
- Scroll the mouse wheel to zoom in or out
- Left click and drag to move the camera along the XY plane
The interesting part
I made a complex function plotter which has the added feature of taking the left side of the screen, the SOR, as input. If you've drawn or loaded an SOR you will be able to see it in the output of the complex function.
The variable z provides the x and y coordinates of each pixel in the form x + iy.
Any other variables will become toggleable uniforms which you can use to manipulate the program.
The x and y axes of each window ranges from -1 to 1. When a user enters a function, each point (x,y) on the right screen is colored by where they land under f(x+iy) on the left screen. In areas not covered by the SOR, a background image helps to visualize where on the complex plane each of the input points landed. Note: the look of this background image is heavily inspired by David Bau's complex function viewer, though I didn't take or look at any of his code when creating it.
To generate the parser for user input I used peg.js. The generated parser file is included, along with the grammar file that I wrote and used to generate the parser.
Note: below u and v are used to represent any expression
Operators and functions:
Grouping (u)
Magniute |u|
Conjuagte u*
Basic arithmetic: u+v,u-v,u*v,u/v
Exponentiation and logarithms: u^v, log(u) (log refers to the natural logarithm, log base e)
Trig functions: sin(u), cos(u), tan(u)
Inverse trig functions: asin(u), acos(u), atan(u)
Hyperbolic trig functions: sinh(u), cosh(u), tanh(u)
Angle: arg(u)
Get real/imaginary components: re(u), im(u)
Iterated function {z'=update, z'=intial, iterations} (Think of z'=update as the body of a for loop, e.g. {z' = z' +1, z' = 0, 5} would intiialize z' to 0, then add one to it in each of 5 iterations).
Derivative w.r.t z (u)' (You can nest derivatives as deeply as you want, but due to the limitations of floating point arithmetic results degrade fairly quickly) Note the parentheses, z' in an iterated function is not the derivative of z.
Integral w.r.t z $u or $(lower)u or $(lower, upper). When the lower and upper bound parameters are omitted, defaults of 0 and z respectively are used. Integrates along a line from lower to upper bound.
Here is a list of interesting functions to try out:
z/t //Take a look at the background without any distortions
|z|*e^(i*arg(z)) //The same as z
cos(sin(z*3)*3)
{z' = z^z' + (z/t) , z'=1, 117} //especially for negative z
{z' = z'^i+ i^(z/t), z'=0, 10}
i^(z/t)
(z/t)^i + i^(z/t)
(z/t)^i * i^(z/t)
(z/t)^i / i^(z/t)
((z/t)^i) ^ ( i^(z/t)) //All combinations of parentheses really
{z' = sin(z'), z'=(z/t), 5} //repeated sin
https://en.wikipedia.org/wiki/Newton_fractal
{z'= z'^2 + t , z'=(z/0.75), 9} //Julia sets
{z' = z'^2 - 1, z'=z/0.75, 8} //Julia set, neat case
{z'= z'^2 + (z-0.5)/t , z'=(z-0.5)/t, 9} //mandelbrot, offset to see the full thing
{z' = (z'/t+1)/(z/t-1), z'=z, 2}
{z' = (z'/t+1)/(z'/t-1), z'=z, 2}
{z' = (z/t+1)/(z'/t-1), z'=z, 2} //really cool, set im to 0 and move t 1 to -1
(z/t)*clen(z/t) - (z/t)^2
-i*log(i*(z/t) + (1 - (z/t)^2)^(0.5i))
$atan(z/t) //really cool looking
Driver HTML File
Screenshot of program: