              Case Study Problem B2 Table Top Cost Analysis Application / Novice level You run a workshop company that does ornamental wooden rectangular or circular tables. Now in your business, you have determined that 90% of a table's estimated price comes from the table top. You want to write a program that when given the dimensions of the table (and its shape), you can immediately estimate the price of the table. The program must first determine the shape of the table (rectangular or circular). Then depending on the shape, you must input the dimensions in feet (length and width for the rectangle, and diameter for the circle). Plus, you need to enter the thickness of the table top in inches. Given this information you can compute the estimated price of the table top using this formula: Estimate cost = Top area x Thickness x \$5 + Thickness x \$8 Show this estimate plus the estimate for the whole table (recall that the 90% of a table's cost lies in the table top). Afterwards, the whole program should repeat unless the user presses Esc.    The Solution  It's so easy! If you're a beginner programmer, this is a nice problem to try especially once you've learned about inputting data and doing calculations. The solution I'm going to present now is a really straightforward one; the kind that a computer science teacher might show to his or her class. First off, we need to know the shape of the table top. Once that information is entered, we can determine what type of dimensions to ask from the user. If the shape is circular, we need the diameter of the table in feet. If the shape is rectangular, we program should ask for the the length and width of the table in feet. Whatever the shape of the table, we need the thickness of the table top in inches. Once we have these data, we can use the given equation to give the estimate cost of the table top and the estimate cost of the whole table. Finally, we print the costs and ask the user whether he or she wants a new estimate. The shape of things to come. To do the first part, (asking the shape of the table), we can simply display the choices (as in a menu) and let the user enter the letter of his or her choice:
 ' Get the table shape PRINT "1. Circle" PRINT "2. Rectangle" PRINT "Enter the number corresponding" PRINT "to the shape of the table: "; INPUT Shape The variable Shape should now contain a number representing one of the two shapes. The dimensions of the table. Depending on the shape of the table, it wi
 TimeNow& = TIMER Hour% = TimeNow& \ 3600 Minute% = (TimeNow& \ 60) MOD 60 Second% = TimeNow& MOD 60 Take note that the variable I used to copy the value of TIMER is in Long Integer format (instead of just Integer). Find the reason why? Now you know how to extract those things. But that is not what we want. (Haha.) We still need the fractional parts of their value. Why? If we just got the integral parts, the clock hands will point at discrete directions. What I mean is, if the time is 4:30, the hour hand will point at four, instead of between four and five. See what I mean? So the correct code should be:
 ' Calculate the time values TimeNow% = TIMER Second% = TimeNow% MOD 60 Minute! = (TimeNow% \ 60) MOD 60 Minute! = Minute! + Second% / 60 Hour! = TimeNow% / 3600 If Hour! >= 12 THEN Hour! = Hour! - 12 Here, we made the second value an integer value. If you want it to have fractional values so that the second hand will move continuously instead of jumping every second, you can do so. The reason why I made it that way is so that we just have to update the clock display every second, instead of continuously (which could be flickery). I've noticed that there's no easy way to get the value for the minutes. I just made it so that I extract the integer value and then I just add the fraction of the minute depending on the second value. By the way, you may notice that we reduced the hour value to 12-hour format instead of the usual 24-hour format since the hour hand makes a complete revolution every 12 hours (actually, it won't really matter in some applications, but we might use a specific range of angles through look-up tables and such...). Converting to the angles. Now that we have the time values in their respective variables, we can now find the angles corresponding to each value. For convenience, we'll redefine the angular system so that 0° points up, to the 12 o'clock position, and the angle values increase in the clockwise direction. So 90° points to the 3 o'clock position, 180° points at 6 o'clock, and so on. I said that the screen mode we should use is SCREEN 12. Well, I plan on not changing the screen coordinate system, which is just like the Cartesian Coordinate System flipped along the x-axis (i.e., the positive x direction goes to the right and the positive y direction goes downwards). And I plan on using the trigonometric functions to convert the angle to the appropriate rectangular coordinates. So my x-coordinate function would be sine (with respect to my choice of angular system) and my y-coordinate function would be negative cosine. Figure out why. With those things out of the way, let's now proceed with the time-value-to-angle functions. By simple computation, we find out that the hour hand moves 30° every hour, while the minute and second hands both move 6° every minute and every second respectively. So we just multiply their corresponding unit interval angle with their values. We also convert the angles to radians since we'll be using the trig functions.
 ' Compute the angles (converted to radians) HrAng! = .523599 * Hour! MnAng! = .104720 * Minute! ScAng! = .104720 * Second% Voila! Now we're through getting the angles! Displaying the clock. The next process is to display the clock. What I'm going to do here is to show a very simple display. The clock would be centered on the screen. It's border will be a circle with a radius of 200 pixels. The hands will just be lines radiating from the center, with the hour hand having a length of 120 pixels, the minute hand 180 pixels, and the second hand 190 pixels. Our center pixel is (320, 240). To make sure that we update the the clock every second instead of continuously, we just do a looping check for the integral value of TIMER and redraw the clock whenever the value changes.
 ' Wait for a second to elapse Timed& = TIMER DO: LOOP UNTIL INT(TIMER) <> Timed& Here is code to draw the hands given the angles:
 ' Compute the hands' endpoints HrX% = SIN(HrAng!) * 120 + 320 HrY% = -COS(HrAng!) * 120 + 240 MnX% = SIN(MnAng!) * 180 + 320 MnY% = -COS(MnAng!) * 180 + 240 ScX% = SIN(ScAng!) * 190 + 320 ScY% = -COS(ScAng!) * 190 + 240 ' Draw the hands LINE (320, 240)-(HrX%, HrY%), 12 LINE (320, 240)-(MnX%, MnY%), 12 LINE (320, 240)-(ScX%, ScY%), 14 Why we still put the coordinates in their own variables will be apparent when we update the clock. Before, we can update the clock, we need to erase the hands first and it would be faster to erase the hands by redrawing over them with the background color instead of doing a CLS. Here's the complete program with all the parts added and combined:
 Listing B3.1  ' Initialization SCREEN 12 ' Clock border CIRCLE (320, 240), 200, 9 ' Previous hand positions PHrX% = 320: PHrY% = 240 PMnX% = 320: PMnY% = 240 PScX% = 320: PScY% = 240 ' Clock display loop DO   ' Wait for a second to elapse   Timed& = TIMER   DO: LOOP UNTIL INT(TIMER) <> Timed&   ' Calculate the time values   TimeNow& = TIMER   Second% = TimeNow& MOD 60   Minute! = (TimeNow& \ 60) MOD 60   Minute! = Minute! + Second% / 60   Hour! = TimeNow& / 3600   If Hour! >= 12 THEN Hour! = Hour! - 12   ' Compute the angles (converted to radians)   HrAng! = .523599 * Hour!   MnAng! = .104720 * Minute!   ScAng! = .104720 * Second%   ' Compute the hands' endpoints   HrX% = SIN(HrAng!) * 120 + 320   HrY% = -COS(HrAng!) * 120 + 240   MnX% = SIN(MnAng!) * 180 + 320   MnY% = -COS(MnAng!) * 180 + 240   ScX% = SIN(ScAng!) * 190 + 320   ScY% = -COS(ScAng!) * 190 + 240   ' Erase the previous hands   LINE (320, 240)-(PHrX%, PHrY%), 0   LINE (320, 240)-(PMnX%, PMnY%), 0   LINE (320, 240)-(PScX%, PScY%), 0   ' Draw the current hands   LINE (320, 240)-(HrX%, HrY%), 12   LINE (320, 240)-(MnX%, MnY%), 12   LINE (320, 240)-(ScX%, ScY%), 14   ' Save the hands' position   PHrX% = HrX%: PHrY% = HrY%   PMnX% = MnX%: PMnY% = MnY%   PScX% = ScX%: PScY% = ScY% LOOP UNTIL INKEY\$ = CHR\$(27)  Here's a sample output: I took this screenshot at around 10:15 pm. A little bit of fancy. That clock display looks very boring. Lets spice it up a little by adding second tick marks on the border and by extending the hands in the other direction by 30 pixels. Here's the revised code (I've highlighted the changes):
 Listing B3.2  ' Initialization SCREEN 12 ' Clock border CIRCLE (320, 240), 220, 9 FOR I% = 0 TO 59   Rads! = I% * 3.14159265# / 30   X1 = SIN(Rads!) * 200 + 320   Y1 = -COS(Rads!) * 200 + 240   X2 = SIN(Rads!) * 210 + 320   Y2 = -COS(Rads!) * 210 + 240   IF I% MOD 5 = 0 THEN     LINE (X1, Y1)-(X2, Y2), 11   ELSE     LINE (X1, Y1)-(X2, Y2), 9   END IF NEXT ' Previous hand positions PHrX1% = 320: PHrY1% = 240 PMnX1% = 320: PMnY1% = 240 PScX1% = 320: PScY1% = 240 PHrX2% = 320: PHrY2% = 240 PMnX2% = 320: PMnY2% = 240 PScX2% = 320: PScY2% = 240 ' Clock display loop DO   ' Wait for a second to elapse   Timed& = TIMER   DO: LOOP UNTIL INT(TIMER) <> Timed&   ' Calculate the time values   TimeNow& = TIMER   Second% = TimeNow& MOD 60   Minute! = (TimeNow& \ 60) MOD 60   Minute! = Minute! + Second% / 60   Hour! = TimeNow& / 3600   If Hour! >= 12 THEN Hour! = Hour! - 12   ' Compute the angles (converted to radians)   HrAng! = .523599 * Hour!   MnAng! = .104720 * Minute!   ScAng! = .104720 * Second%   ' Compute the hands' endpoints   HrX1% = SIN(HrAng!) * 120 + 320   HrY1% = -COS(HrAng!) * 120 + 240   MnX1% = SIN(MnAng!) * 180 + 320   MnY1% = -COS(MnAng!) * 180 + 240   ScX1% = SIN(ScAng!) * 190 + 320   ScY1% = -COS(ScAng!) * 190 + 240   HrX2% = -SIN(HrAng!) * 30 + 320   HrY2% = COS(HrAng!) * 30 + 240   MnX2% = -SIN(MnAng!) * 30 + 320   MnY2% = COS(MnAng!) * 30 + 240   ScY2% = -SIN(ScAng!) * 30 + 320   ScY2% = COS(ScAng!) * 30 + 240   ' Erase the previous hands   LINE (PHrX2%, PHrY2%)-(PHrX1%, PHrY1%), 0   LINE (PMnX2%, PMnY2%)-(PMnX1%, PMnY1%), 0   LINE (PScX2%, PScY2%)-(PScX1%, PScY1%), 0   ' Draw the current hands   LINE (HrX2%, HrY2%)-(HrX1%, HrY1%), 12   LINE (MnX2%, MnY2%)-(MnX1%, MnY1%), 12   LINE (ScX2%, ScY2%)-(ScX1%, ScY1%), 14   ' Save the hands' position   PHrX1% = HrX1%: PHrY1% = HrY1%   PMnX1% = MnX1%: PMnY1% = MnY1%   PScX1% = ScX1%: PScY1% = ScY1%   PHrX2% = HrX2%: PHrY2% = HrY2%   PMnX2% = MnX2%: PMnY2% = MnY2%   PScX2% = ScX2%: PScY2% = ScY2% LOOP UNTIL INKEY\$ = CHR\$(27)  Here's the output to that program. The modifications I made to the program deal with drawing the second tick marks around the border and the addition of six new variables to track the position of the other endpoint of every hand. Looks better, doesn't it? Further Exploration  Try creating more fancier clock displays! If you'll download the B3 Zip file, you'd find the previous two programs plus one more program showing the possibilities.   Go back to the Case Study page. Home Page | Program Nook | Instructional | Open Forum Portfolio | Visitor's Area | Connections | About the Site Copyright © 1997-1999, SEAV Softwares. All rights reserved. Webmaster: Eugene Villar (SEAV); e-mail: [email protected]