Subject: Test message (This message is being sent to all CPSC 215/801 students and TA's) This is a test of the facility that will be used to distribute information to the class. If you are no longer in the class and would like your name removed please let me know. If you are in the class and DON"T get this message you should let me know also ;-) mw Subject: Assignment 1 (This message is being sent to all CPSC 215/801 students and TA's) The specification for assignment 1 is now available in /home/westall/class/215/assns/assn1.f04.html Subject: Hints on assn1 (This message is being sent to all CPSC 215/801 students and TA's) 1 - On the use of malloc(). When you use malloc() in a program you should have in the includes at the top of your program. #include #include The malloc() function is defined to return a pointer of type void*. So if you want to avoid a warning message you will usually want to CAST the pointer to the type you are trying to allocate: e.g. float* pf; int* pi; pf = (float *) malloc(100); pi = (int *) malloc(10); These casts don't really change any values but they do eliminate the warnings. 2 - Using stdin and stdout for input and output. When we use stdin and stdout for input and output we will ALWAYS use redirection to associate these names with real data files. As an example, the proper way to run p3 to convert a color file to grayscale would be: p3 grayscale < color.ppm > mygrayfile.pgm When redirection is used in this way, reads from stdin will actually consume data from a file named color.ppm and will get EOF when that file has been fully processed. Futhermore the redirection related components of the command line will not appear in the argv[] array. Subject: Dangerous declarations (This message is being sent to all CPSC 215/801 students and TA's) I recommend that variables be declared individually with a single line per declaration. Today I helped a student find a problem caused by: char* buffer, loc; Because of the way C binds the * operator it turns out that is equivalent to: char* buffer; char loc; which was not what the student wanted! Subject: Quiz preparation (This message is being sent to all CPSC 215/801 students and TA's) Some folks are starting to accumulate enough poor quiz scores to be a cause for concern... Here on some "helpful hints" on how to turn this around 1 - Simply coming to class and paying attention is not in itself sufficient to get the job done. The volume of material covered and the rate at which it is covered mandate outside study. 2 - However, coming to class AND paying attention IS an excellent way to MINIMIZE the amount of study required outside class. 3 - The answers to all virtually all quiz questions appear verbatim in the class notes posted on the web. So these notes are a GOOD thing to study. 4 - The quiz questions will concentrate on topics that I say are of high importance and/or easy to get confused by and/or are a common source of errors. Often RED ink in the notes is a good indicator. 5 - In general I would recommend that you try to spend at least 1/2 an hour on the day of the class going back over the notes trying to ensure that understand the material. 6 - Then try to spend an hour reviewing on the day of the quiz. 7 - If you don't understand something, (1) ask at the start of class, or (2) come by my office, or (3) send me e-mail. Subject: gdb and input redirection (This message is being sent to all CPSC 215/801 students and TA's) I believe that the Solaris version of gdb is somewhat brain damaged with regard to redirection in that it does not look in your current working directory for the file from which you are trying to redirect your input. Instead it appears to look only in your home directory. There are two approachs you can use to defeat this: 1 - put the image file in your home directory you want to use in your home directory. or 2 - specify the full path name run < /home/joeuser/215/prog1/testimg.ppm Both alternatives worked for me. Subject: Processing of general .ppm headers (This message is being sent to all CPSC 215/801 students and TA's) When reading the <
>, I recommend you use fgets() to read one line of text at a time. To test for comments all you have to do is test the first character in the buffer and see if it is #. If it is a # that means entire line is a comment so you just read another line and repeat the test. When you find lines that don't start with #, the easiest way to extract the numeric values is to use strtok() with a delimeter string of char* delim=" \t\n"; and then use atoi() to convert the number from ascii to an int. Subject: which C compiler (This message is being sent to all CPSC 215/801 students and TA's) Your programs will generally be tested on both an intel archtecture solaris machine (e.g. jmw) and a sparc architecture (e.g. torpedo7). The compiler used in both environments will be /usr/local/bin/gcc So that is what I recommend that you develop with. Subject: Test images (This message is being sent to all CPSC 215/801 students and TA's) Several students have asked about the availability of test images produced by me. For the remainder of the course it is important that you learn how to drive the xv tool on Unix. So it is advisable that you start now and create your own images. To create a test image load any image (gif, jpg, tiff, etc) with xv on a solaris system. If you don't have ANY image go to any web site and using the mozilla browser on a Unix system, right click on the image and save it. When xv loads the image, right click on the picture and with the menu comes up click save. When the save menu comes up click format. When the format menu comes up select PBM/PGM/PPM(raw). Then enter a name for your image (e.g. my_pic.ppm) in the box at the bottom of the save menu. The halfmoonbay.ppm used in Lab 1 remains available in the same location. A program that can sucessfully process only images created by xv will get at least 95% credit. Subject: CLUG and Linux (This message is being sent to all CPSC 215/801 students and TA's) Since the Linux environment is 99% compatible with the Solaris environment with regard to requirements of this and subsequent CPSC courses, you will find it useful to have your notebook computer dual boot Linux and M$Ware. If you don't have experience in working with Linux, the fine folks at CLUG (Clemson Linux Users Group) are an excellent resource who can help you get Linux installed. A CLUG member who is also as student in CPSC 215 Subject: How to run p3 (This message is being sent to all CPSC 215/801 students and TA's) The way in which p3 should be run is: p3 grayscale < halfmoonbay.ppm > half.pgm or p3 floyd < half.pgm > half.pgm If the argument is "grayscale" then an error message should be printed if the 1st two bytes of the ppm file is not P6 If the argument is "floyd" then an error message should be printed if the bytes are not P5. Subject: How to submit assignment 1 (This message is being sent to all CPSC 215/801 students and TA's) NOTE: This procedure has NOTHING in common with "handin" nor "sendlab" Do NOT even TRY think about how they fit into the procedure because they DON"T!! You must turn in 3 files: p1.c p2.c and p3.c Do NOT turn in any image files, core files, makefiles etc. If you used any private .h files do turn them in. 1. From a departmental Solaris system rlogin to workstation jmw 2. The submission directories lie in the directory /local/jmw2/215/a1 which is available ONLY IF YOU HAVE LOGGED INTO WORKSTATION jmw. Each student has a subdirectory of /local/jmw2/215/a1. The name of your subdirectory is your userid (in the example we will assume your id is wjsmith). 2. copy (via the cp command) required files to your subdirectory in /local/jmw2/215/a1 For example: cp /home/wjsmith/215/a1/*.c /local/jmw2/422/a1/wjsmith Here you would (hopefully) obviously need to replace /home/wjsmith/215/a1/*.c with wherever you have your programs. 3. don't modify the permissions on your subdirectory. They are set so that ONLY you can access your directory. ---------------- After you think you have turned your programs in, its a good idea to cd /local/jmw2/215/a1/wjsmith and make sure your files are their and they still compile and work correctly. The programs are due by Monday night at 11:59 pm, but I would recommend submitting them an hour or so early in case you hit some snags in the procedure. You may replace your submission at any time, but you will incur the appropriate late penalty if you do so after the deadline. Since the penalty grows slowly at first, if you submit a badly broken program on Monday and manage to get it working perfectly by Wednesday it is to your advantage to replace it then. Even if all you have on Monday is a badly broken program you should submit it as well, because there is no guarantee it will be any better by Wednesday. Subject: Nasty bug in notes (This message is being sent to all CPSC 215/801 students and TA's) The notes yesterday suggested using: 1.0 * (x / v->win_x_size) * v->world_x_size; This is broken and should be: (1.0 * x / v->win_x_size) * v->world_x_size; or ((1.0 * x)/ v->win_x_size) * v->world_x_size; or (double)x / v->win_x_size) * v->world_x_size; Assignment: Why was the original wrong and how does the correction fix it? Thanks to Craig Baker for pointing this out. mw Subject: Operating "in the dark" (This message is being sent to all CPSC 215/801 students and TA's) I lost power at home on Thursday night and still have no indication when it will return so I've been having to learn how to operate in the dark. Its an inconvenient, inefficient and generally frustrating way to get things done. Unfortunately, it appears that some students are also operating in the dark when it comes to USING (not just programming) computer systems and networks. I've been told that assignments could not be turned in because the McAdams doors were locked and that assignments could not be worked on remotely because Windows doesn't have a .ppm viewer(despite the fact that a Google search reveals googles of .ppm viewers). It is easy to get logged in to jmw.cs.clemson.edu from any system connected to the Internet (assuming you have a valid ID.) From off campus: ssh access.cs.clemson.edu then ssh jmw From on campus: ssh jmw.cs.clemson.edu If you have never heard of ssh and/or don't have it installed upon your laptop, the fine folks at the DCIT help desk in Martin can help you out. ssh has a friend named scp that is also useful for copying files back and forth between your personal system and the CPSC systems. Unfortunately, the version of scp that is presently installed on the CPSC systems IS an old an obsolete version and you may find it works in only one direction ... especially if your home system is a modern Linux distribution. In this case it will generally work FROM a CPSC system to an external system but often will NOT not work the other. However, when I tried scp this morning from a Windows XP system located on campus, it did seem to connect to jmw.cs.clemson.edu and work fine. From off campus you should try to use scp to access.cs.clemson.edu. I haven't tried that today, so your mileage may vary. I generally recommend AGAINST doing your development on your Windows machine if you can possibly avoid that. As mentioned earlier a good way to avoid it is to have the fine folks at CLUG help you convert your laptop to a dual boot machine that runs Linux. If you should try to use Visual Studio you should be aware that Mr. Gates will inspect EVERY byte you write to stdout with printf() or fwrite() and if he sees \n = 0x0a he will convert it to the two byte sequence 0x0d 0x0a Needless to say, this will have a negative impact on the quality of your image! The only way I know to defeat this behavior is something along the lines of the following: FILE *myout; #ifdef MSWARE myout = fopen("bill.ppm", "wb"); stdout = myout; #endif This should disable redirection and all writes to the standard about should go to file bill.ppm. Advanced M$ programmers probably know of a better way to do this. ------------------- In conclusion, when I ask folks who don't like and/or struggle mightily with programming "Why do you persist in majoring in CPSC?" I sometimes hear -- "Even though I don't like programming I really do like: system administration and/or installing new software and getting it to work and/or learning how to use complex software systems and helping others to do so". This is a very reasonable response. On the other hand, if you find ALL of the above unpleasant and frustrating you really should give serious thought to redirecting your career objectives. Two excellent guidelines in choosing career objectives are (1) pick something you REALLY like to do and (2) pick something in which your skill set is compatible with the competition. As a young guy, I REALLY liked golf. By the time I was 20 I had a 2 handicap and had shot a few sub-70 rounds in competition -- but on easy courses. But by the time I was 22, my game hadn't noticeably improved and I could see that my skill set was compatible with being head pro at a driving range!! Thirty years of doing that didn't sound like fun. So I settled on working with computers, and the rest is history! mw Subject: On semicolons and structures (This message is being sent to all CPSC 215/801 students and TA's) Several folks have pointed out that I have confused them with the structure definition placed in the notes. This structure was presented as struct blah_type { int x; } A structure definition may be followed by the name of a variable creating an instance of a structure, the name of a type if typedef precedes struct, or if this is a standalone structure type definition it MUST be followed by a ; struct blah_type { int x; }; Sorry for creating this confusion. mw Subject: More concrete requirements for the ray tracer (This message is being sent to all CPSC 215/801 students and TA's) These are now available in assn2.f04.html in the class directory. Subject: Updated notes with linear algebra details (This message is being sent to all CPSC 215/801 students and TA's) In class tomorrow we will go over (rather quickly) the theory behind how to determine if and where a ray hits a sphere or a plane. These are presented in pretty fine detail to hopefully make your job of converting them to C code simple. However, I think it useful for you to look over that BEFORE I go over it in case something is not quite as clear as I thought it would be! Subject: Header file structure (This message is being sent to all CPSC 215/801 students and TA's) I should have probably stressed this more in class, but your own PRIVATE headers must be included as follows: #include "ray.h" and NOT #include ------------------------------------- In building a multi-module program you MUST resist the tempation to include .c files in an attempt to "help out" the linker. The linker is a very robust character and needs no help from you. <<<<<<<<>>>>>>>>>>>>>>> do the following: /* main.c */ #include "sphere.c" #include "light.c" #include "model.c" ----------------------------------- A reasonable way to manage your .h files is the approach that I normally use /* ray.h */ #include #include #include #include #include typedef ... (list type) typedef ... (object type ) typedef ... (sphere type ) etc .... #include "rayhdrs.h" /* end ray.h */ ----------------- /* rayhdrs.h */ double hits_sphere(....... double hits_light(......... etc /* end rayhdrs.h */ -------------------- Then each module (main.c, sphere.c , etc.. ) #include "ray.h" and it will automagically get the standard includes plus all the headers you need. Subject: building programs containing the veclib (This message is being sent to all CPSC 215/801 students and TA's) I apologize for not emphasizing this more heavily because it has tripped a number of folks. Around page 52 of the class notes you will see the makefile that I used to build my program. At the tail end of the gcc used to link all the .o files togther you will see -lm (That is lower case letter l followed by lower case m and preceded by hyphen.) Even though the linker is a capable character sometimes one has to tell him where to look for stuff. The -lm is instructing him to include the mathematical function library which contains the sqrt() function. So to build the veclib3d test program something like gcc -g vecmain.c veclib3d.c -lm should suffice. Subject: light intensity (This message is being sent to all CPSC 215/801 students and TA's) The image I displayed last week was produced by a version of the code that had the lack of attenuation bug in it. For correct code to produce a similar image you will need to crank the emissivity of the light up to about 10 and will will also have to up the ambient parameter as well. Subject: debugging "hits" functions (This message is being sent to all CPSC 215/801 students and TA's) As you no doubt have (or will) discovered, firing 640x480 rays produces enough debugging output to cause you to lose sanity quickly. The proper way to initially test "hits" is to create a screen with world dimensions 8 x 6 and view point 4, 3, 4, create a single sphere at location (4, 3, -4) with radius 1. After running load_model() just call hits_sphere() directly from main passing it the viewpt, a direction of (0, 0, -1) and a pointer to the sphere object. t should come back 7. If it doesn't its now easy to step through with gdb or printf() and figure out what when wrong. If it does return 7, then test with few other directions (0.05, 0.0, -1) etc and see if things remain sane. If they do, hits is working. So if the image you produce isn't, it probably means the mk_image is probably passing ray_trace a broken direction vector. You can test for that by changing the loops in mk_image to start and the middle of the pix_map (i.e. only shoot one ray). Subject: even more help on debugging "hits" functions (This message is being sent to all CPSC 215/801 students and TA's) The proper way to initially test "hits" is to create a screen with world dimensions 8 x 6 and view point 4, 3, 4, create a single sphere at location (4, 3, -4) with radius 1. After running load_model() just call hits_sphere() directly from main passing it the viewpt, a direction of (0, 0, -1) and a pointer to the sphere object. If you do the above D = (0, 0, -1) C = (4, 3, -4) B = (4, 3, 4) B'= (0, 0, 8) So: D dot D = 1 2(B' dot D) = -16 B' dot B' = 64 r^2 = 1 So a = 1 b = -16 c = 63 b^2 - 4ac = 256 - 252 = 4 t = (-(-16) - sqrt(4)) ----------------- 2 = 16 - 2 14 ------ = --- = 7 2 2 Subject: On malloc'd objects and "memory leaks" (This message is being sent to all CPSC 215/801 students and TA's) In helping students with their programs I've noticed a couple of recurring problems which are generally symptomless. This leads me to believe I overemphasized one aspect of dealing with pointers while underemphasizing another. Problem one goes like this: obj_t *temp = malloc(sizeof(obj_t)); temp = list->head; while (temp != NULL) -- do stuff -- The declaration of temp "mallocs" a structure of type obj_t and points "temp" to the structure. This was probably motivated by my insistence that a pointer NEVER be "used" before it is intialized to point to something useful. However, in this case the pointer IS correctly initialized by the statement: temp = list->head and now points to the first object in the list. The problem is that the area of storage returned by malloc is now "forever" lost, because "temp" was the only thing we had that pointed to it and now temp points elsewhere. Therefore the proper declaration in this case is simply: obj_t *temp; Another way to look at this is to think: "I don't ever need to "malloc()" an area of memory unless I'm going to write into that memory!" ----------------------------------------- Another problem I've seen is along the lines of: { double *univec = malloc(3 * sizeof(double)); vl_unitvec3(dir, univec); : return; } Now this is not the same as the first problem because here the memory that is allocated is used in the call to vl_unitvec3(). So we DO need the malloc here. The problem is that the memory is never freed and so when a return is made from this function that memory is again "forever" lost. If the function is called enough before the program ends the program could fail due to running out of memory. The proper solution to this problem is to free(univec); before returning from the function in which it was allocated. A good rule of thumb here is that any storage that has been allocated MUST be freed before the last pointer to it is lost. ------------------------------------------------------- The above discussion could tempt one to overcompensate in the other direction. Namely in load_sphere { obj_t *new_obj; : new_obj = malloc(sizeof(obj_t); : if (list->head == NULL) { list->head = list->tail = new_obj; } else { list->tail->next = new_obj; list->tail = new_obj; } --> free(new_obj); <--- FATAL Non-Symptomless BUG return(0) Needless to say it is IMPERATIVE that the temptation to do this be resisted!! Unlike the case with univec above, this storage object will be referenced throughout the program and even though the value of the pointer new_obj is lost on return from load_sphere the storage remains accessible through the list links. If the "free" is included here the next time an object is allocated the same storage will be "recycled" and two objects will (unsuccessfuly) be attempting occupy the same storage. ------------------------------------------------------------- The Java language provides for "automagic" garbage collection in which storage for an object is magically reclaimed when the last reference to the object no longer exists. C provides no such mechanism and so it is important the C programmers be aware of the the time at which the last pointer to malloc'd storage is about to disappear and use the free() function call to release the storage before that happens. In the case that the last pointer persists until the end of the program (as would be the case for the obj_t objects and associated sphere_t's in the raytracer) it is NOT really necessary to free them all at the very end of the program because the Operating System will reclaim ALL memory used by the program. Subject: Assignment 1 graded (This message is being sent to all CPSC 215/801 students and TA's) I will be sending back shortly grade reports on assignment 1. These were graded by me and not the TA's so don't blame them ;-) The test input images and sample output images are in directory assns/assn1data F-15.ppm - input to p1, p2, and p3 grayscale out6.ppm - input to p3 floyd F15b.ppm - p2 output F15c.pgm - p3 grayscale output out6b.pgm - p3 floyd output doit - script used to run the tests eval.txt - input to script It takes about 6 hours just to determine whether these things are working or not and report what appears to be broken. I definitely cannot identify every bug in every program. However, if you think your program was working correctly and after testing with the above data and comparing with the sample output, you STILL think it is working correctly please come see me. If you did something like adding an unclosed comment at the last minute which massively broke your program, also come see me. If you can identify a <> mistake that led to a massive deduction, I will fix that and test again and if the program now works give you some credit back. Subject: Assignment 2 milestone update (This message is being sent to all CPSC 215/801 students and TA's) An updated milestone describing addition of an infinite plane object type is now in: http://www.cs.clemson.edu/~westall/215/assns/assn2.f04.html There is an example input specification and sample image in /home/westall/class/215/examples/in6.txt /home/westall/class/215/examples/out6.ppm This milestone should lead to the creation of a new module called plane.c which contains functions analogous to those found in sphere.c I built mine in about 30 minutes by cp sphere.c plane.c and then hacking away. (Learning how to use the global change command of your editor to change all sphere_t to plane_t is useful here. ) typedef struct plane_type { double normal[3]; /* normal to the plane */ double point[3]; /* a point on the plane */ } plane_t; ----------------------------------------------------------- Things to watch out for: ======================== Although it took me only 30 minutes to build it immediately didn't work. It took me another 30 minutes to notice I had left off the () in t = (ndotq - ndotb) / ndotd; which is definitely fatal. After that it seemed to work well until I invented in6.ppm With planes and spheres together it appeared that the plane which was supposed to be at floor level was amputating the tops of spheres in wierd and wondrous ways. It took me almost 3 hours of "looking for bugs in all the wrong places" on sat afternoon to discover that I had assumed a unit "dir" vector in "hits_plane" and I was passing a unit vector from ray_trace, but I WASN"T passing a unit_vector from light_visible(). This caused the distances to get screwed up and the floor to appear nearer to some lights than the spheres. So this kind of stuff definitely happens to old and experience C programmers as well as rookies. The last bug so far (there is no such thing as finding the last bug) was in the data. The plane I had intended to be the floor had a point (1, 1, 0) instead of (1, 0, 1). This caused the plane to be 1 unit above the ground. Today when I added the test discussed in class that the value of "t" be at least as large as the distance to the screen, the resulting image had a big black stripe across the bottom as if looking under a raised floor in a computer room. It took me another 30 minutes of trying to figure out what was wrong with hits_plane before I finally got a clue and checked out the input data. Subject: Unit vectors (This message is being sent to all CPSC 215/801 students and TA's) As I reported previously in the "looking for bugs in all the wrong places" message, failure to use a unit vector when one is required may lead to seriously non-obvious program failures. In contrast, repeatedly converting unit vectors to unit vectors simply wastes computer time! Wasting time is bad, but seriously non-obvious program failures are worse! Exercise: how can you find code locations in which you ALWAYS do redundant conversions. As usual there is a potential overcompensatory problem. Conversion of the coordinates of a POINT in 3-D space (as opposed to a vector) has the potential to seriously mess you up. So it is necessary that you keep the distinction between entities (POINTS) that represent locations (e.g. the center of a sphere) and entities (VECTORS) that represent directions (e.g. the difference when one point is subtracted from another) clear. Subject: DON"T use a "min-dist" to test plane hit points (This message is being sent to all CPSC 215/801 students and TA's) A perceptive student asks: > You also mentioned that the t-value we obtain in hits_plane > should be greater than the distance from the viewpoint to the > screen. Does that mean we should pass the viewpoint as a > parameter to the hits_plane function? If that's the case, I'll > have to add that parameter as well to the hits_sphere function > as well. The "min-dist" approach was discussed in class at the time the plane was introduced. It seemed like an excellent idea at the time, but as is common in the development of large programs excellent ideas often turn into "oops" down the road. I initially used the "min-dist" approach myself but discovered the "oops" when I wrote my own specular lighter. Its probably the bug that I knew I had found but couldn't remember the day specular lighting was discussed. When specular lighting is involved, rays "bounce". At areas near the junction between two planes they may bounce a very short distance before hitting the second plane. Therefore using the distance from the viewpoint to the screen (which is a safe minimum with ambient and diffuse lighting) will BREAK SPECULAR LIGHTING IN SPECTACULAR fashion!! The solution (which I will recommend up-front in future renditions of this course) is simple: For all objects, UNLESS THE OBJECT HIT IS A LIGHT, after you have computed the hitpoint, if the Z-coordinate of the hitpoint is > 0.0 return -1 (We do want LIGHTS to be able to shine through the screen). Note that in our environment legit non-light objects must lie in the NEGATIVE Z-coordinate half of the world). If this change to your program appears to cause it to break, it is demonstrating that it was broken all along! The most likely cause for the problem is firing the ray in WRONG DIRECTION. Subject: Upside down pictures (This message is being sent to all CPSC 215/801 students and TA's) If your picture appears to be coming out upside down, it probably is. A good way to test is to render a single sphere with center at (4, 0, -3) and see if it comes out at the top of the picture The cause is the following: If your mk_image() is doing something like: for (y = 0; y < ... ) for (x = 0; x < ... ) Then you are working from the bottom to the top of the picture in world coordinate space. This is fine. However, it is the case that it is assumed in .ppm files that the first row of pixels in the file goes AT THE TOP OF THE PICTURE and so on. Therefore if you are tracing as above AND you put the pixels associated with the first row you trace at the START OF THE PIXMAP YOU BUILD. You WILL get an upside down image. Tracing as shown above you need to put the first row you trace in the LAST ROW of the pixmap; the second row in the next to last row of the pixmap;,.... and the last row you trace should be the first row of the pixmap. Subject: On sensible development methodology (This message is being sent to all CPSC 215/801 students and TA's) You should never, ever attempt to move on to another milestone until you have spent SERIOUS effort testing the current milestone and despite your best efforts to do so you are unable to find any errors, anomalies, unexplicable behavior, or other general "wierdocities". ANY time you write new code, you will inevitably introduce errors. When the new errors start interacting with the old ones that you haven't fixed yet in wierd and wonderous ways, you will have a real mess on your hands the neither you (nor I) will be able to figure out how to fix. Subject: Mid-term test (This message is being sent to all CPSC 215/801 students and TA's) The mid-term test will be given in class this Thursday 14, OCT. The content will mostly be taken directly questions on the daily quizzes and mild variations thereof. I have placed all of them in /home/westall/class/215/quizzes There will likely also be one small program to write. The test will be closed book and closed notes. Subject: Yet another grade recording malfunction (This message is being sent to all CPSC 215/801 students and TA's) I regret to report that we have had yet another quiz grade recording problem in section 1. To receive proper credit for quiz C you will need to turn it back in. You may either do this today, or if you wish to keep the quiz to study by, you may turn it in with your test on Thursday. Due to a Professor malfunction you probably don't have q es labeled quiz C in your possession or NO quizzes labeled quiz C (you might have two quiz B's). Subject: Quiz F answers (This message is being sent to all CPSC 215/801 students and TA's) Here are the answers to quiz F 1 - Recursion is only needed for specular light 2 - we don't test the object the ray just bounced off of 3 - 2 (U dot N) N - U There is no "global" key available. People in possession of keys assembled from answers copied from the board are strongly encouraged to share. Subject: Reminder regarding approved sources of help (This message is being sent to all CPSC 215/801 students and TA's) As stated in the policies distributed in class the ONLY approved sources of aid on any assignment are me and the TAs. Collaboration with other students and/or use of materials from previous semesters is SPECIFICALLY prohibited. Please be careful to ensure these policies are scrupulously adhered to, and if you see any of your classmates engaged in activities counter to these policies please let me know. jmw Subject: Specular problem: Limiting ray bounce distance (This message is being sent to all CPSC 215/801 students and TA's) I believe I have failed to warn you regarding the dreaded ping-pong ray syndrome. It only applies to specular lighting so if you aren't working with specular light yet this will not affect your program. The problem is that if the image def creates a perfect ping-pong of ray bouncing the recursion will never end (until you blow out of stack or heap space and the program segfaults). The solution is easy. At the very start of ray_trace() add if (total_dist > MAX_DIST) return(0.0); Use MAX_DIST of about 30 or so. Sorry about the oversight. mw Subject: How to submit assignment 2 (This message is being sent to all CPSC 215/801 students and TA's) Sorry about the delay in getting these set up. Because of the lateness I will GRANT a 1 DAY EXTENSION. NOTE: This procedure has NOTHING in common with "handin" nor "sendlab" Do NOT even TRY think about how they fit into the procedure because they DON"T!! You must submit subdirectories for all milestones! However, only the code in the highest numbered subdirectory will be tested. So if you have a partially completed but generally broken milestone, DO NOT SUBMIT IT. Do NOT turn in any image files, core files. If you used any private .h files do turn them in. 1. From a departmental Solaris system rlogin to workstation jmw 2. The submission directories lie in the directory /local/jmw2/215/a2 which is available ONLY IF YOU HAVE LOGGED INTO WORKSTATION jmw. Each student has a subdirectory of /local/jmw2/215/a2. The name of your subdirectory is your userid (in the example we will assume your id is wjsmith). 2. copy (via the cp command) required files to your subdirectory in /local/jmw2/215/a2. The example below assumes that your directory, /home/wjsmith/215/a2, has ms1, ms2, ms3, etc as subdirectories. For example: cp -r /home/wjsmith/215/a2 /local/jmw2/422/a2/wjsmith After you have copied the files cd to /local/jmw2/422/a2/wjsmith and make sure they are still there and that your raytrace will still build and function correctly. 3. don't modify the permissions on your subdirectory. They are set so that ONLY you can access your directory. ---------------- Subject: Correction: How to submit assignment 2 (This message is being sent to all CPSC 215/801 students and TA's) DO submit makefiles. DON"T submit core, .ppm, .log, .err etc. Sorry for the confusion. Subject: memory leaks (This message is being sent to all CPSC 215/801 students and TA's) One student was having a problem in which his program either consumed excessive time and/or segfaulted and died when trying to do diffuse lighting on a complicated scene. On review of his code I saw that one or two vectors of three doubles were be allocated and not freed on each entry to raytrace, comp_diffuse, hits_xxxx, norm_xxx. Though total number of <> of the malloc() function was small, and the amount allocated at each call also small, in an 800 x 600 raytrace with a large number of objects the total number of calls to malloc was IMMENSE. When I simply changed all allocations of temporary vectors from malloc() to the alloca() function described in this weeks lab. Run time dropped from several minutes to 10 seconds! So if you are suffering from slow performance, make sure you are not leaking because leaks eventually change from poor performance to segfaults. Subject: sample color image with specular effects (This message is being sent to all CPSC 215/801 students and TA's) The example image that I described in class today along with its specification file are in the examples directory and are named flag.ppm and flag.txt. Thanks much to Jonathan Goforth of Section 2 for an excellent design and "stress test" for a raytracer. Both Jonathan and I render the same image so we believe there is a least a reasonable chance that it is close to being correct!(Recall previous warnings in class about the perils of overconfidence in asserting program correctness ;-) It seems to take about 6 and 1/2 minutes to do an 800 x 600 on my office machine. Subject: turning in assn 2 (This message is being sent to all CPSC 215/801 students and TA's) I notice a good number of you are not compliant with this specification: 17 Do NOT turn in any image files, core files. 18 If you used any private .h files do turn them in. If you submitted image files, debug log files or core dumps, please clean 'em out now! ---------------------------------------------------------- If you have an input image specification that you believe your program works well with and you would like me to use it (in addition to my own test files) in evaluating your ray tracer, please name it myfile.txt and place it in the the directory that contains the milestone you would like for me to evaluate. If you don't name it myfile.txt my grading system WILL NOT see it. If you already have one in the directory all you need to to is ssh to jmw and cd to the directory and rename the file myfile.txt Add ONLY THAT ONE FILE TO YOUR SUBMISSION. DO NOT re-submit all of your code or you will give yourself a big and unnecessary late penalty!! Subject: Lab on Nov 3 (This message is being sent to all CPSC 215/801 students and TA's) Wednesday labs will meet as scheduled this week. This will cause the labs to become temporarily "out of sync". The Tuesday lab will catch up with the Wednesday lab the week of thanksgiving. Subjects: Office hours Tuesday a.m. (This message is being sent to all CPSC 215/801 students and TA's) I must attend a Ph.D. defense at 11:00 am tomorrow and thus will not be in the office between 11:00 and 12:30. If you need to see me, I plan to be there between 9:30 and 11:00. mw Subject: Potential for disaster(s) in veclib3d.c (This message is being sent to all CPSC 215/801 students and TA's) I just spent an hour helping a student track down a truly evil and subtle bug that was causing rotations not to work: Here is the offending code: 51 void vl_xform3 ( double m1[3][3], double* v1, double* v2) 52 { 53 v2[0] = vl_dot3(m1[0],v1); 54 v2[1] = vl_dot3(m1[1],v1); 55 v2[2] = vl_dot3(m1[2],v1); 56 } /* vl_xform3 */ The bug is particulary pernicious because doesn't always show its face. Namely vl_xform3(rot, base, newbase); will work fine 100% of the time... but if you do a vl_xform3(rot, base, base); you have just done yourself in!!! The correct way to construct the module to avoid the potential for this evilness is: 51 void vl_xform3 ( double m1[3][3], double* v1, double* v2) 52 { double w[3]; 53 w[0] = vl_dot3(m1[0],v1); 54 w[1] = vl_dot3(m1[1],v1); 55 w[2] = vl_dot3(m1[2],v1); memcpy(v2, w, sizeof(w)); 56 } /* vl_xform3 */ You should ensure that ALL of your veclib functions will work correctly if the one of the input vectors is also an output. Subject: Holiday opportunity for raytracers (This message is being sent to all CPSC 215/801 students and TA's) Last week a student inquired about the possibilities of of defining planes of finite size. Such planes can be used to insert visible planar rectangles of arbitrary size into a raytraced image. They can also be used to construct rectangular solids such as boxes and cubes. But perhaps their most interesting property is their use in texture mapping. This facility allows arbitrary images such as your own digital photographs to be incorporated into a raytraced scene. Crudimentary examples of what can be done along with notes on how to do it are available in texture.pdf in the notes directory. The examples there show only the application of textures to planar objects, but simple extensions will permit you to texture cylinders and slightly less simple extensions allow texturing of spheres. Subject: More sample inputs/images (This message is being sent to all CPSC 215/801 students and TA's) I have added a few more sample input / images to the examples directory: multicyl.txt - fairly simple with 4 cyl cylex.txt - more complicated cylinder example spot?.txt - a couple of spotlight example tiled-spot.txt - this is the double spheres over the tiled floor with tiled back wall that appears in the notes. I had to manually convert the file from C++ format input -- please let me know if I got it wrong. As usual, I have no knowledge that these are incorrect but no way to prove them correct either. Subject: Error in sample inputs/images (This message is being sent to all CPSC 215/801 students and TA's) The tiled-spot.txt file had an error which I think is fixed as of 9:00 am Tuesday. (Reflectivity and geometry in the second sphere were out of order). Thanks to Jonathan Goforth for point this out. mw Subject: More Errors in sample inputs/images (This message is being sent to all CPSC 215/801 students and TA's) The original multicyl.ppm image was an old image produced by a buggy version of my tracer. If your image looks like that one, you probably failed to use a unit vector where you needed to. It has now been replaced by one thought to be correct. Thanks to Anthony Ponce for finding this one. mw Subject: Correct order for material reflectivites (This message is being sent to all CPSC 215/801 students and TA's) There are some comments in some sample files that are holdovers from the grayscale days and are thus MISLEADING. Material reflectivity should be specified as follows: 0.2 0.2 0.2 Ambient (R,G,B) 4.0 4.0 4.0 Diffuse (R,G,B) 0.4 0.4 0.4 Specular (R,G,B) The above description should produce a GRAY object: Sorry for the confusion and thanks to Rebekah Moore for pointing it out. mw Subject: How to submit assignment 3 (This message is being sent to all CPSC 215/801 students and TA's) NOTE: This procedure has NOTHING in common with "handin" nor "sendlab" Do NOT even TRY think about how they fit into the procedure because they DON"T!! You must submit subdirectories for all milestones! However, only the code in the highest numbered subdirectory will be tested. So if you have a partially completed but generally broken milestone, DO NOT SUBMIT IT. Do NOT turn in any image files, core files. Points WILL be deducted for failure to follow this procedure. If you used any private .h files do turn them in. 1. From a departmental Solaris system rlogin to workstation jmw 2. The submission directories lie in the directory /local/jmw2/215/a3 which is available ONLY IF YOU HAVE LOGGED INTO WORKSTATION jmw. Each student has a subdirectory of /local/jmw2/215/a3. The name of your subdirectory is your userid (in the example we will assume your id is wjsmith). 2. copy (via the cp command) required files to your subdirectory in /local/jmw2/215/a3. The example below assumes that your directory, /home/wjsmith/215/a3, has ms1, ms2, ms3, etc as subdirectories. For example: cp -r /home/wjsmith/215/a2/* /local/jmw2/422/a2/wjsmith After you have copied the files cd to /local/jmw2/422/a2/wjsmith and make sure they are still there and that your raytrace will still build and function correctly. 3. don't modify the permissions on your subdirectory. They are set so that ONLY you can access your directory. 4. MAKE REAL SURE your msn directories are immediate subdirectories of the directory whose name is your userid. I don't want any intermediate layers such as assig3 or some such that makes me have to wander through a large directory tree in search of the holy grail. 5. Lame and juvenile attempts at humor such as naming files and directories m*****f*****n may have made you to coolest guy in the class in Middle School, but its time to try to grow up a little bit now. Such naming conventions will also be awarded a nice fat deduction for failure to comply with specs. ---------------- Subject: bug in multicyl.ppm image (This message is being sent to all CPSC 215/801 students and TA's) To be consistent with earlier restrictions regarding hit locations, hit points on the viewer side of the screen should be disallowed. However, my cylinder code did not have the test if (obj->hitloc[2] > 0) return(-1); So if your multicyl.ppm image matches mine, you probably don't either! When you put the test in you should get something along the lines of multicyl2.ppm. (This test MUST be applied AFTER applying the inverse rotation and translation to the hitpoint -- but the height test MUST be applied before) Thanks to Adam Griffis for pointing this out. mw Subject: Use of NULL (This message is being sent to all CPSC 215/801 students and TA's) The value NULL should be used in assignments to and comparisons with POINTER values only. Comparing doubles to NULL with modern compilers will generate a syntax error at compile time. Please clean any of those that you might have out of your submission. Subject: Spotlight glints (This message is being sent to all CPSC 215/801 students and TA's) It has been approximately asked: ----------- I have a problem with the spotlight of the raytracer. I noticed that the spotlight itself was being reflected by objects. When using spot2.txt I got 2 little dots on the sphere coming from the source of the spotlight ----------- This is likely an artifact of how I dealt with spotlights. If the bounce from the viewpoint off a specular surface hits the spotlight it seems that it should should show up. However, this relates to the problem of whether a spotlight should be viewed as an infinitesimal point source (which would be necessary if the illuminated area were a true cone with the spotlight center at the vertex) or a bogo light sphere. In the former case you would not see the light reflected off the object, but in the latter you would. When I discussed this in class I kind of took both sides of the issue because there really isn't an easy answer. To be truly faithful to reality with a spherical light source inside a spot cone it would be necessary to "back off" the vertex from the center of the sphere to where it would have to be in order to cram the sphere into the cone. I didn't want to get into that so technically any way you deal with the spot light (other than that way) is wrong. It is OK if your spotlight does (or does not) produce specular glints. It is also fine if you do it correctly by backing off the cone vertex! Thanks to Rebekah Moore and Adam Griffis for independently encountering this issue and bringing it up. Please continue to remember this project is NOT a team effort! mw Subject: raytracer test data (This message is being sent to all CPSC 215/801 students and TA's) see a2t?.* in the examples directory for images used in testing grayscale raytracer. Subject: Quiz grades (This message is being sent to all Section - 2 students) I will shortly be sending each of you my record of your quiz grades. The number next to your ID is your current average. There will be 2 makeups given at the time of the exam and there might be an additional drop so this will go up some. The remaining numbers are the individual quiz scores ordered with MOST RECENT SCORES FIRST -- e.g. quiz 1 is the LAST number. An x means we think you missed the quiz. A zero means you took the quiz but got a 0. Subject: Lab grades: Mr. Rich's section / Quiz grades: sec 1 (This message is being sent to all CPSC 215/801 students) If you are a student in Mr. Daniel Rich's lab sections it is important that you READ THIS MESSAGE. (For those of you who are unsure, Mr. Rich has dark hair, Mr. Freeman has red hair). Last evening Mr. Rich informed me that, despite my specific instructions to the contrary, he has committments that apparently are so important that he feels they override his committments to his TA position, and that he will be leaving Clemson for semester break effective Tuesday evening. He has ensured me that all of his students will receive all of their lab evaluations by sometime today. Both TA's have been reminded that they were to distribute quiz grades to section 1 students (I have already distributed section 2 quiz grades). If either of these turn out not to be the case by tomorrow morning, please notify me and be specific regarding what is missing. Since Mr. Rich is leaving, if you have questions regarding the grading of your labs it IT IS IMPERATIVE THAT YOU TAKE THEM UP WITH HIM SOMETIME MONDAY or TUESDAY. I recommend you e-mail him, dkrich@cs.clemson.edu, to set up an appointment. If he is not responsive to your e-mail, please let me know ASAP. I apologize for this situation. I will distribute assignment grades by wednesday. jmw Subject: More grade recording malfunctions (This message is being sent to all CPSC 215 Sec-2 / 801 students) I don't know if its just me getting old or too many TA's or what but we have more grade recording problems this semester than in the total previous 30 I've been here. Anyhow, the test 1 (midterm test) grades are presently filed in parts unknown. Therefore please bring test 1 (the midterm test) with you to the final exam. Subject: Final raytracer evaluations (This message is being sent to all CPSC 215 Sec-2 / 801 students) I will be sending these out shortly. Test cases and output images are now in the examples directory. Model description files are named a3t?.txt where ? varies between 1 and 9. Output files are a3t?l.ppm. If your program produced no images and thus received a terrible score simply because your input parser was defective, feel free to tweak the input to your needs and send me a tarball <<< CONSISTING ONLY OF NEW VERSIONS OF a3t?.txt FILES -- NOT new images and NOT new code >>> and I'll be glad to try your program again -- and only deduct for the broken parser if that fixes the problems. Many of you will receive a message to the effect of "diagonal planes too bright". This will apply to yellow and cyan diagonal planes in a3t3.txt. The probable cause for this is failure to convert the plane normal vector to a unit vector before performing diffuse lighting. If you don't get a report AND you haven't previously been advised to see me regarding something I don't understand in your code, then that means I don't think you submitted an assignment. If you think you DID submit an assignment please let me know ASAP so that I can try to track down what happened. Subject: Extra time for labs and/or assignments (This message is being sent to all CPSC 801 students) It was requested that I grant an extra day for DPA students to complete the 215 labs. While I sympathize with your situation, I believe it is not in your own best interest for me to do that. For you to be successful in courses such as CPSC 605 and CPSC 611 it is necessary not only that you approach skill level parity with the "average" CPSC 215 student, but that you exceed it. Therefore, it would give you an incorrect perception of your own position if I were to make your requirements considerably more lax than theirs. I will however use different grading curves for 801 and 215 and probably weigh later lab grades (when you should have achieved parity with 215 students) more strongly than the earlier ones. Practice programs - CPSC 801 - Oct 20, 2004 1 - Write the null program. It consists only of a main() function with no code between the {}. 2 - Write a program which will print the word Hello followed by a new-line. 3 - Write a program which will declare a single integer as a local variable, assign it the value 99 and then print out the variable. 4 - Write a program which uses the "scanf()" function to read in a single integer value and print it out. 5 - Write a program which uses the "scanf()" function to read in a single integer value and print out the word "non-negative" if the value is greater than or equal to zero and "negative" otherwise. 6 - Write a program which contains a while loop in which a counter is used to control the number of times the code within the loop is executed. The counter should be initialized to 0. In each iteration of the loop the value of the counter should be printed and then the value of the counter incremented. The loop should end after the value 9 is printed. 7 - Write a program which contains a while loop in which scanf() is used to read a single integer value per iteration of the loop and printf is used to print it out. 8 - Write a program which contains a while loop in which scanf() is used to read a single integer value per iteration of the loop. At end of file your program should print the sum of the all the values read. 9 - Write a program which contains a while loop and uses scanf() to read a single integer value from the standard input (keyboard or redirection) and computes the sum of the integers. While the program is running it should also count the number of values in the file. When the program completes in should print a single line that looks like the following: Read 5 values. The sum was 13. Your objective is, starting with a blank textedit page, to be able to write any of these programs correctly within a short time frame. The ONLY way to achieve this objective is to practice until you are successful. Then wait a day or so and practice until you are successful.. Then wait a day or so and practice until you are successful.. If you get stuck on any problem e-mail the problem id and your current best effort to both me and to mick and we will get back to you in short order. mw 1 - Write a program which reads a single integer "n" from the standard input and the value of n! = 1 x 2 x 3 x.. x n 2 - Write a program which reads a single integer "m" from the standard input and prints the first integer "n" for which n! >= m 3 - Write a program which reads a collection of integers from the standard input. The "i-th" value (i = 0, 1, 2, ..) should be weighted by -1^i and the weighted sum of the integers computed and printed. e.g. input: 1 3 4 -2 5 output = 1 -3+4+2-5 = -1 4 - Write a program in which an array of 100 integers is created. The values in the array should be set using the recurrence a_0 = a_1 = 1 and a_n = a_{n-1} + a_{n-2}. After all values have been set, print them to the standard output in another loop. 5 - Write a program which produces the same output as the one just written but does so in a single loop and without the use of an array. 6 - Write a program in which an array of 100 double precision floating point values is created. The array should be loaded by reading from the standard input until end of file is reached. When this occurs, print the numbers in the reverse of the order in which they were read. 7 - Write a program which reads from the standard input two double precision numbers per iteration of a loop. For each pair of numbers, print on a single line the two numbers followed by the quotient when the first number is divided by the second. As usual the program should exit when end of file is encountered. Here are this weeks programs ... it is important that all students attain a level of proficiency at which starting from a blank text editor file any one of this (or last) weeks programs can be done in less than 5 minutes. One way to ensure that such is the case is to repeat solving the problems until such is the case. There may be others but that one is the only way I'M SURE WILL WORK. Subject: Practice programs As before if you get stuck on any of these e-mail your present best effort to me or Mick and we will get you going again. 1. Write a program which will read in two integers from the standard input and print "yes" if the first integer is evenly divisible by the second. 2. Write a program which will read in a single integer from the standard input and print out both in input integer and the largest integer that evenly divides it. 3. Write a program which will read a list of integers from the standard integer and print out each integers along with the largest integer that divides it evenly. For this program you should convert the core of the previous program to a function called int gdiv(int num) which returns the greatest divisor. 4. Write a program which will read in a single pair of integers and print out both integers along with the largest integer that evenly divides BOTH of them. 5. Write a program which will read a list of integer pairs from the standard input and print the input pair along with the greatest common divisor. Here you should create a function called int gcd(int i1, int i2) which returns the greatest common divisor. 1. Write a function called swap that will interchange the value of two integers; void swap(int *a, int *b) { } main() { int x = 6; int y = 17; swap(&x, &y); printf("x = %d and y = %d \n", x, y); } 2. Write a main() function which contains an array of 20 ints. It should read numbers from the standard input into the array until end of file is encountered and then <> print the numbers out. 3. Add a third loop between the read loop and the print loop. In this loop if array[0] < array[1] you should swap their values via a call to the swap function.. Then if array[1] < array[2] you should swap their values. Countinue until each pair of numbers has been tested and swapped if necessary. 4. Move the code in the middle loop to a separate function called /* make a pass over the array swapping as required */ void makepass( int arrray[], /* The array I'm to work on */ int count) /* the number of values it contains */ { } 5. Add a for () loop to the main() program which simply calls make pass count - 1 times where count is the number of values in this array.