TweetFollow Us on Twitter

Apr 97 Challenge

Volume Number: 13 (1997)
Issue Number: 4
Column Tag: Programmer's Challenge

Programmer's Challenge

By Bob Boonstra, Westford, MA


For the Challenge this month, we return to the topic of computer graphics - you'll be solving a simplified rendering problem. Your Challenge is to create the image formed by a set of polygons on a specified projection plane, as viewed from a specific viewpoint, and as illuminated from a point light source. You will need to perform hidden surface elimination, create shadows caused by the light source, and project the image as it would be seen by someone at the viewpoint. You will be performing multiple projections from a given viewpoint, so this Challenge includes an initialization routine as well as a calculation routine, both of which are included for timing purposes in determining the winner.

The prototype for the code you should write is:

#define kMAXPOINTS 10

typedef struct My2DPoint {/* point in z==0 plane */
 float x2D; /* x coordinate */
 float y2D; /* y coordinate */
} My2DPoint;

typedef struct My3DPoint {
 float x3D; /* x coordinate */
 float y3D; /* y coordinate */
 float z3D; /* z coordinate */
} My3DPoint;

typedef struct My3DDirection {
 float thetaX;   /* angle in radians */
 float thetaY;   /* angle in radians */
 float thetaZ;   /* angle in radians */
} My3DDirection;

typedef struct MyPlane {
 My3DDirection planeNormal; /* normal vector to plane */
 My3DPointplaneOrigin;  /* origin of plane in 3D space */
} MyPlane;

typedef struct MyPolygon {
 long   numPoints; /* number of points in polygon */
 My2DPointthePoint[kMAXPOINTS];  /* polygon in z==0 plane */
 MyPlanepolyPlane; /* rotate/translate z==0 plane to this plane */
 RGBColor polyColor/* the color to draw this polygon */
} MyPolygon;

void InitProjection(
 My3DPoint*viewPoint,/* viewpoint from which to project */
 My3DPoint*illumPoint,  /* viewpoint from which to draw shadow */
 void   *storage,/* auxiliary storage preallocated for your use */
 long   storageSize/* number of bytes of storage */

void CalcProjection(
 GWorldPtroffScreen, /* GWorld to draw projection */
 MyPolygonthePolys[],/* polygons to project */
 long   numPolys,/* number of polygons to project */
 My3DPoint*viewPoint,/* viewpoint from which to project */
 My3DPoint*illumPoint,  /* illumination point from which to draw
        shadow */
 void   *storage,/* auxiliary storage preallocated for your use */
 long   storageSize/* number of bytes of storage */

Your InitProjection routine will be provided with a pointer to auxiliary storage (storageSize bytes, at least 1MB) preallocated for your use, along with the viewPoint from which projections are to be made and the illumPoint location of an illumination source from which shadows are to be created. InitProjection may perform any calculations that may be useful for multiple CalcProjection calls that follow. CalcProjection will be provided the same parameters given to InitProjection, along with the number (numPolys) and location of the polygons to be projected, and the offScreen GWorld in which the projection is to be drawn. CalcProjection should calculate the way thePolys would look from viewPoint, projected onto a projection plane normal to the viewPoint vector and passing through the origin. Hidden surface elimination must be performed so that obscured polygons or parts of polygons are not seen. The image of the projection is to be rendered in the GWorld pointed to by offScreen, with the projection plane mapped to the z==0 plane in the GWorld. Polygons must be rendered in the appropriate polyColor, subject to the limitations of the GWorld. Polygons are the same color on both sides. Parts of the projection plane not filled by projections of polygons should be black.

In addition to projecting the polygon image as seen from viewPoint, you must also project the shadow of thePolys created by an illumination source at illumPoint, onto the projection plane and onto the image of other polygons, as seen from viewPoint. Shadows should be rendered in the color of the surface in shadow, using a 50% gray pattern. All polygons have a flat matte surface, creating no specular reflections of the illumination source. The illumPoint will be on the same side of the projection plane as the viewPoint.

Polygons are specified in 2-dimensional coordinates in the z==0 plane, to ensure that all points are coplanar, along with a planeNormal vector that specifies the orientation of the polygon plane and a planeOrigin that specifies the plane origin. The last vertex of a polygon is connected to the first vertex to close the polygon (i.e., a square would have four vertices, not a fifth that is the same as the first.) The true polygon coordinates to be projected are calculated by first rotating counterclockwise about the positive z axis by thetaZ (i.e., the positive x axis rotated 90 degrees maps to the positive y axis), then counterclockwise about the positive x axis by thetaX (i.e., positive y rotates to positive z), then counterclockwise about the positive y axis by thetaY (i.e., positive z rotates to positive x), and finally by translating the origin to the planeOrigin point. In matrix form, the transformation is:

 | X |   | x3D |            | x2D |
 | Y | = | y3D | + Ry Rx Rz | y2D |, where
 | Z |   | z3D |            |  0  |

      | cos(thetaZ) -sin(thetaZ)        0     | 
 Rz = | sin(thetaZ)  cos(thetaZ)        0     |
      |       0            0            1     |

      |       1            0            0     |
 Rx = |       0      cos(thetaX) -sin(thetaX) |
      |       0      sin(thetaX)  cos(thetaX) |

      | cos(thetaY)        0      sin(thetaY) | 
 Ry = |       0            1            0     |
      |-sin(thetaY)        0      cos(thetaY) |

The offScreen GWorld will have a pixelDepth of 32. The viewPoint and illumPoint will have z coordinates greater than zero, but thePolys may have coordinates with arbitrary values (after rotating and translating the polyPlane). The projection plane is opaque, meaning that any part of a polygon behind the projection plane is invisible, creating no projection and no shadow.

On average, CalcProjection will be called approximately 10 times with the same viewpoint and illumPoint, but different polygons, for each call to InitProjection. The code producing the fastest projection, including both the InitProjection and CalcProjection times, will be the winner.

This will be a native PowerPC Challenge, using the latest CodeWarrior environment. Solutions may be coded in C, C++, or Pascal.

Three Months Ago Winner

Perhaps it was the short amount of time to work with the BeOS CD-ROM bundled in the January issue of the magazine, or the fact that the BeOS required a 604 PowerMac, or some minor installation anomalies with the BeOS, or to migration of interest to a prospective NeXT-OS - whatever the reason, only two people entered the BeSort Challenge. Congratulations to Charles Higgins for submitting the fastest solution to the BeSort Challenge. The problem itself was fairly simple: write a SortWindow class that would sort a list of character strings by one of three methods, two specified by the problem statement and one of your own choosing.

Both Charles and the second contestant, Kenneth Slezak, implemented the required bubble sort and exchange sort methods, and both used the quicksort algorithm for the third method. The main difference in efficiency was in the technique used to swap list elements. Charles exchanged the pointers in the list and invalidated the list view to cause the list to be redrawn. Kenneth deleted the items to be exchanged from the list and added the items back into the list in the reverse order. On my 8500, the former was faster by 10+%. Interestingly enough, when run on a BeBox, the latter was ~5% faster. Since the problem statement called for evaluation on the Macintosh, Charles' solution is the winner.

One other interesting observation - in the winning solution, execution time was dominated by display time. I verified this by repeating the timing tests with the windows hidden. In the winning solution, this reduced execution time by almost 80%. In Ken Slezak's solution, execution time was dominated by the list additions/deletions used to swap list elements, so the difference in results is much smaller.

A straightforward optimization to the winning solution improved execution time significantly. Instead of invalidating the ListView each time two elements were exchanged, one need only invalidate the rectangles for the two items being exchanged. This change reduced execution time by some 30% when the windows were visible. (It actually hurt performance when the windows were not visible.)

The table below provides the execution times and code sizes for each two solutions submitted, plus the optimized version of the winning solution. It shows the time, in seconds, required to sort a list of 500 strings by each of the three sort methods, with either visible windows or invisible windows.


Here are the Top Contestants for the Programmer's Challenge. The numbers below include points awarded over the 24 most recent contests, including points earned by this month's entrants.

1.Munter, Ernst18211.Nicolle, Ludovic21
2.Gregg, Xan11412.Picao, Miguel Cruz21
3.Larsson, Gustav6713.Brown, Jorg20
4.Lengyel, Eric4014.Gundrum, Eric20
5.Lewis, Peter3215.Higgins, Charles20
6.Boring, Randy2716.Kasparian, Raffi20
7.Cooper, Greg2717.Slezak, Ken20
8.Antoniewicz, Andy2418.Studer, Thomas20
9.Beith, Gary2419.Karsh, Bill19
10.Cutts, Kevin2120.Nevard, John17

There are three ways to earn points: (1) scoring in the top 5 of any Challenge, (2) being the first person to find a bug in a published winning solution or, (3) being the first person to suggest a Challenge that I use. The points you can win are:

1st place   20 points    5th place              2 points
2nd place   10 points    finding bug            2 points
3rd place    7 points    suggesting Challenge   2 points
4th place    4 points

Here is Charles Higgins' winning solution:


Charles Higgins

#include "SortWindow.h"

void swap(BWindow *aWindow, char **s1, char **s2);
char **addlist( BWindow *aWindow, char **list, int numberOfThings);
SortWindow::SortWindow(BRect frame)
         : BWindow(frame, "Sort", B_TITLED_WINDOW, 0)
   BRect            aRect = frame;
   BListView       *aView;
   aView = new BListView(aRect, "SortView", 
                          B_FOLLOW_ALL, B_WILL_DRAW);

void swap(BWindow *aWindow, char **s1, char **s2)
   BView   *aView;
   char    *temp;
   aView = aWindow->FindView("SortView");
   temp = *s1;
   *s1 = *s2;
   *s2 = temp;

char **addlist( BWindow *aWindow, char **list, int numberOfThings)
   BListView       *aView;
   int              i;
   aView = (BListView*)aWindow->FindView("SortView");
   for(i=0;i< numberOfThings;i++)

void SortWindow::DoSort(
   char *thingsToSort[], int numberOfThings, SortType sortMethod)
   short            i,
                    sorted = FALSE;
   char           **myList;
   myList = addlist( this, thingsToSort, numberOfThings);
      case kBubbleSort:
         i = numberOfThings-1;
               if (0 < strcmp(myList[k],myList[j]))
                  j = k;
            swap( this, &myList[i], &myList[j]);
      case kExchange:
            sorted = TRUE;
               if(0 < strcmp(myList[i],myList[i+1]))
                  sorted = FALSE;
                  swap( this, &myList[i], &myList[i+1]);
      case kMySort:
         QuickSort( myList, 0, numberOfThings);

void SortWindow::QuickSort( char **list, int first, int last)
   int              j,i;

   while(last - first > 1)
      i = first;
      j = last;
         while(++i < last && strcmp(list[i],list[first]) < 0)
         while(-j > first && strcmp(list[j],list[first]) > 0)
         if (i >= j)
         swap( this, &list[i], &list[j]);         
      if( j == first)
      swap( this, &list[first], &list[j]);      
      if(j - first < last - (j+1))
         QuickSort( list,first,j);
         first = j + 1;
         QuickSort( list,j+1,last);
         last = j;


typedef enum SortType {
 kBubbleSort = 1,
 kExchange = 2,
 kExchangeSort = 2,
 kMySort = 3
 } SortType;

class SortWindow : public BWindow {

 SortWindow(BRect frame);

virtual void DoSort( char *thingsToSort[],
     int numberOfThings,
     SortType sortMethod);
virtual void QuickSort( char **list, int first, int last);



Community Search:
MacTech Search:

Software Updates via MacUpdate

AirPort Utility 6.3.6 - Set up and manag...
Note: Most recent release available only within OS X 10.11 El Capitan update. Use AirPort Utility to set up and manage your Wi-Fi network and AirPort base stations, including AirPort Express, AirPort... Read more
Quicksilver 1.3.1 - Application launcher...
Quicksilver is a light, fast and free Mac application that gives you the power to control your Mac with keystrokes alone. Quicksilver allows you to find what you need quickly and easily, then act... Read more
Tidy Up (Five Users) 4.1.5 - Find duplic...
Tidy Up is a complete duplicate finder and disk-tidiness utility. With Tidy Up you can search for duplicate files and packages by the owner application, content, type, creator, extension, time... Read more
Mellel 3.4.3 - The word processor of cho...
Mellel is the leading word processor for OS X and has been widely considered the industry standard since its inception. Mellel focuses on writers and scholars for technical writing and multilingual... Read more
Skype - Voice-over-internet p...
Skype allows you to talk to friends, family and co-workers across the Internet without the inconvenience of long distance telephone charges. Using peer-to-peer data transmission technology, Skype... Read more
Bookends 12.6.0 - Reference management a...
Bookends is a full-featured bibliography/reference and information-management system for students and professionals. Access the power of Bookends directly from Mellel, Nisus Writer Pro, or MS Word (... Read more
Apple iBooks Author 2.4 - Create and pub...
Apple iBooks Author helps you create and publish amazing Multi-Touch books for iPad. Now anyone can create stunning iBooks textbooks, cookbooks, history books, picture books, and more for iPad. All... Read more
Web Snapper 3.3.9 - Capture entire Web p...
Web Snapper lets you capture Web pages exactly as they appear in your browser. You can send them to a file as images or vector-based, multi-page PDFs. It captures the whole Web page - eliminating the... Read more
Tunnelblick 3.6beta10 - GUI for OpenVPN...
Tunnelblick is a free, open source graphic user interface for OpenVPN on OS X. It provides easy control of OpenVPN client and/or server connections. It comes as a ready-to-use application with all... Read more
EtreCheck 2.5.1 - For troubleshooting yo...
EtreCheck is a simple little app to display the important details of your system configuration and allow you to copy that information to the Clipboard. It is meant to be used with Apple Support... Read more

Camel Up (Games)
Camel Up 1.0.0 Device: iOS Universal Category: Games Price: $4.99, Version: 1.0.0 (iTunes) Description: | Read more »
The Martian: Bring Him Home (Games)
The Martian: Bring Him Home 1.0 Device: iOS Universal Category: Games Price: $2.99, Version: 1.0 (iTunes) Description: Based on the best selling novel and critically acclaimed film, THE MARTIAN tells the story of Astronaut Mark... | Read more »
This Week at 148Apps: September 21-30, 2...
Leap Into Fall With 148Apps How do you know what apps are worth your time and money? Just look to the review team at 148Apps. We sort through the chaos and find the apps you're looking for. The ones we love become Editor’s Choice, standing out above... | Read more »
Tweetbot 4 for Twitter (Social Networki...
Tweetbot 4 for Twitter 4.0 Device: iOS Universal Category: Social Networking Price: $4.99, Version: 4.0 (iTunes) Description: *** 50% off for a limited time. *** | Read more »
Mori (Games)
Mori 1.0 Device: iOS Universal Category: Games Price: $2.99, Version: 1.0 (iTunes) Description: Stop, rewind and unwind with Mori. Time is always running, take a moment to take control. Mori is an action puzzle game about infinitely... | Read more »
100 Years' War (Games)
100 Years' War 1.0 Device: iOS Universal Category: Games Price: $3.99, Version: 1.0 (iTunes) Description: | Read more »
Tower in the Sky (Games)
Tower in the Sky 0.0.60 Device: iOS Universal Category: Games Price: $1.99, Version: 0.0.60 (iTunes) Description: | Read more »
hocus. (Games)
hocus. 1.0.0 Device: iOS Universal Category: Games Price: $.99, Version: 1.0.0 (iTunes) Description: New, polished, mind-bending, minimal puzzle game with dozens of levels and extra-ordinary design Features:- Beautifully crafted... | Read more »
Mos Speedrun 2 (Games)
Mos Speedrun 2 1.0 Device: iOS Universal Category: Games Price: $1.99, Version: 1.0 (iTunes) Description: Mos is back, in her biggest and most exciting adventure ever! Wall-jump to victory through 30 mysterious, action packed levels... | Read more »
3D Touch could be a game-changer, but it...
Were you one of the lucky/financially secure enough ones to buy a new iPhone 6s or iPhone 6s Plus over the weekend? Yup, me too (I’m not convinced I was either of those two things, but let’s go with lucky for now), so I thought I’d delve into just... | Read more »

Price Scanner via

Apple offering refurbished 2015 13-inch Retin...
Apple is offering Certified Refurbished 2015 13″ Retina MacBook Pros for up to $270 (15%) off the cost of new models. An Apple one-year warranty is included with each model, and shipping is free: -... Read more
Apple refurbished 2015 MacBook Airs available...
Apple has Certified Refurbished 2015 11″ and 13″ MacBook Airs (the latest models), available for up to $180 off the cost of new models. An Apple one-year warranty is included with each MacBook, and... Read more
Adobe Photoshop Elements 14 Gets Haze Removal...
The latest iteration of Adobe’s powerful consumer image editing appliction Photoshop Elements 14 analyzes your photo and removes background haze, so your shot looks sharp all the way to the horizon... Read more
Apple refurbished 15-inch Retina MacBook Pros...
Apple has Certified Refurbished 2015 15″ Retina MacBook Pros available for up to $380 off the cost of new models. An Apple one-year warranty is included with each model, and shipping is free: - 15″ 2... Read more
21-inch iMacs on sale for up to $120 off MSRP
B&H Photo has 21″ iMacs on sale for up to $100 off MSRP including free shipping plus NY sales tax only: - 21″ 1.4GHz iMac: $1029.99 $70 off - 21″ 2.7GHz iMac: $1229 $70 off - 21″ 2.9GHz iMac: $... Read more
Bare Bones Software Releases TextWrangler 5.0...
Bare Bones Software has announced the release and immediate availability of TextWrangler 5.0, a major upgrade to its free, high performance, general purpose text editor for Mac OS X. Built on a new,... Read more
Apple refurbished iPad Air 2s available for u...
Apple has Certified Refurbished iPad Air 2s available for up to $140 off the price of new models. Apple’s one-year warranty is included with each model, and shipping is free: - 128GB Wi-Fi iPad Air 2... Read more
Save up to $100 on Mac AppleCare Protection P...
Adorama has 3-Year AppleCare Warranties on sale for up to $100 off MSRP including free shipping plus NY & NJ sales tax only: - Mac Laptops 15″ and Above: $249 $100 off MSRP - Mac Laptops 13″ and... Read more
Updated Mac Price Trackers
We’ve updated our Mac Price Trackers with the latest information on prices, bundles, and availability on systems from Apple’s authorized internet/catalog resellers: - 15″ MacBook Pros - 13″ MacBook... Read more
27-inch 3.5GHz 5K iMac on sale for $81 off MS...
Adorama has the 27″ 3.5GHz 5K iMac on sale for $2218.99, $81 off MSRP, including a free copy of Apple’s 3-Year AppleCare Protection Plan, plus a free external DVD/CD drive, and a copy of Corel... Read more

Jobs Board

Senior Payments Security Manager - *Apple*...
**Job Summary** Apple , Inc. is looking for a highly motivated, innovative and hands-on senior payments security manager to join the Apple Pay security team. You will Read more
*Apple* Solutions Consultant - Retail Sales...
**Job Summary** As an Apple Solutions Consultant (ASC) you are the link between our customers and our products. Your role is to drive the Apple business in a retail Read more
*Apple* Site Security Manager - Apple (Unite...
**Job Summary** The Site Security Manager is a high-profile security position at Apple . The Site Manager is the face of Apple Global Security (GS) and primary point Read more
*Apple* Fulfillment Operations Execution Ana...
**Job Summary** The AMR Apple Fulfillment Operations Team is seeking a talented team player to drive the Apple Online Store (AOS) fulfillment performance to ensure a Read more
*Apple* Distinguished Educator (ADE) Communi...
**Job Summary** Apple is seeking candidates for a new position on the Apple Distinguished Educator (ADE) Program team as ADE Community Support Manager. Join a team Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.