Computer Graphics
CAP 4730

 

Fall 2000
Tuesday/Thursday 9:30am
103 Love Building
Dr. David C. Banks

 

Computer Graphics
Homework 05
6 hours
 
Copyright © 2000 David C. Banks

  1. 1.00 hours
    Sampling a circle (with rejection).

    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

    Put the image on your Web page.

    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;
    
      }
    
  2. 2.00 hours
    Sampling a sphere (with rejection).

    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.

  3. 2.50 hours
    Sphere intersections.


    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

    Suggestion: use a lot of rays to increase the chance that some of them will hit the target sphere SU.

    Take a screen shot of your .iv file as displayed by ivview. Convert to VRML. Link from your Web page.

  4. Extra credit (100 points)

    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.

  5. Extra credit (100 points)

    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
    

  6. 0.50 hours
    Notebook.

    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.