|
Computer Graphics |
Fall 2000
|
Computer Graphics
Homework 05
6 hours
Copyright © 2000 David C. Banks
Write a function pointOnCircle() that produces a random point on a (unit) circle. Get random values of x, y using drand48(), scaling and translating each of them to the range (-1, 1). Keep trying until the point is inside the unit disk. Normalize to produce a point on the unit circle. NOTE: read the man page for drand48; you need to initialize the random seed with srand48() or else you will get the same random points every time. Suggestion: use getpid() as your seed.
Use or modify the example code below.
void
pointOnCircle(double &x, double &y)
{
float length;
const int maxAttempts = 10;
do
{
x = 2.0 * (drand48() - 0.5);
y = 2.0 * (drand48() - 0.5);
length = sqrt(x*x + y*y);
}
while ( ((length > 1.0) || (length == 0.0)) && (--maxAttepts) );
if ( (length <= 1.0) && (length > 0.0) ) // Normalize.
{
x /= length;
y /= length;
}
else // throw exception
{
}
}
Create a program circleSamples that randomly samples points on the circle, then outputs the image in .ppm format. Parse the command line so you can specify
NOTE: converting from (x,y) coordinates to pixels is fairly simple. If you have not already written a conversion routine, now is the time to do it. Use or modify the code below. Suggestion: create a CoordinateSystem class that contains the min and max values. Then create a changeCoords() method with fewer parameters.
// Convert from (u,v) into (s,t) coordinates
//
// First, convert (u,v) into "canonical" unit coordinates
// that go from (0,0) to (1,1).
//
// The sequence goes: translate, scale, rescale, retranslate.
void
changeCoords(float u, float v, float uMin, float uMax, float vMin, float vMax,
float &s, float &t, float sMin, float sMax, float tMin, float tMax)
{
s = u;
t = v;
// Translate so that (uMin, vMin) is at the origin.
s -= uMin;
t -= vMin;
// Scale to a unit-length coordinate system
s /= uMax - uMin;
t /= vMax - vMin;
// Next, convert from these unit coordinates into the
// (s,t) coordinate system.
// Rescale from the unit-length coordinate system
s *= sMax - sMin;
t *= tMax - tMin;
// Retranslate the origin to (sMin, tMin).
s += sMin;
t += tMin;
}
Write a function pointOnSphere() that produces a random point on a (unit) sphere.
Create a program sphereSamples
that randomly
samples points on the sphere, then outputs
the scene in Inventor format. Make it parse the
command line for parameters. An example .iv file
is given below.
#Inventor V2.1 ascii
Complexity
{
value 1.0 # use high-quality meshes
}
Separator
{
Material
{
emissiveColor 0.9 0.5 0.4 # red, green, blue
diffuseColor 0.0 0.0 0.0 # non-reflective
ambientColor 0.0 0.0 0.0 # non-reflective
}
Transform
{
translation 0.0 0.0 0.0 # centered at the origin
}
Sphere
{
radius 0.2
}
}
Separator
{
Material
{
emissiveColor 0.0 0.0 0.0 # non-emissive
diffuseColor 0.9 0.5 0.4 # bluish reflector
ambientColor 0.0 0.0 0.0 # non-reflective
}
Transform
{
translation 1.0 0.0 0.0 # centered at (1, 0, 0)
}
Sphere
{
radius 0.5
}
}
Suggestion: write a Sphere class with the method outputToInventor() so that a Sphere can write out its parameters in Inventor format.
Use ivview to view your image. Take a screenshot and put it on your Web page. Convert the .iv file to VRML (.wrl) and link it from your Web page.

Write a program rayCast1.
The program will sample random directions
around a 3D viewpoint (vx,vy,vz) supplied by the command line.
Write a Sphere::intersect() method that takes a point p0
and direction dp as arguments, then determines the nearest
intersection point along the ray (if it exists).
Put a sphere in the scene (center and radius specified by the command line). Output an Inventor file containing
Take a screen shot of your .iv file as displayed by ivview. Convert to VRML. Link from your Web page.
Type "man SoCylinder" to see the fields that specify a Cylinder{} scene-object. Type "man SoTransform" to learn about rotating an object. Make your program output little cylinders to indicate the rays that intersect the sphere in the scene. Then ivview, screenshot, .wrl, link.
Make the program read from a file (filename supplied by the command line) that describes the geometry of the scene. For example, the file might contain the following scene description.
<scene> <! Glowing white and reflective > <sphere radius="1.5" center="1.0 2.0 -5.0" emittance="0.5 0.5 0.5" reflectance="1.0 1.0 1.0"> </sphere> <! Glowing pink and less reflective > <sphere radius="2.0" center="5.0 -4.0 -2.0" emittance="5.0 3.0 3.0" reflectance="0.5 0.5 0.5"> </sphere> </scene>
Or you can invent a simpler definition like below.
objects 2
sphere r 1.5 c 1.0 2.0 -5.0 e 0.5 0.5 0.5 refl 1.0 1.0 1.0
sphere r 2.0 c 5.0 -4.0 -2.0 e 5.0 3.0 3.0 refl 0.5 0.5 0.5
Print out your Web page. Tar, gzip your code, headers, Makefile, README and link them. Print out your Makefile and README. Put in your notebook.