5. GUI Design

This section outlines a basic GUI for beam loading analysis.

5.1 How the BeamCAD Program Was Designed

5.1.1 Objectives:

• The program is expected to aid the design of beams by taking basic information about beam geometry and material, and then providing immediate feedback. The beam will be simply supported, and be under a single point load. The program should also provide a printed report on the beam.

5.1.2 Problem Definition:

• The basic theory for beam design is available in any good mechanical design textbook. In this example it will not be given.

• The inputs were determined to be few in number: Beam Type, Beam Material, Beam Thickness, Beam Width, Beam Height, Beam Length, Load Position, Load Force.

• The possible outputs are Cross Section Area, Weight, Axial Stiffness, Bending Stiffness, and Beam Deflection, a visual display of Beam Geometry, a display of Beam Deflection.

5.1.3 User Interface:

5.1.3.1 - Screen Layout (also see figure):

• The small number of inputs and outputs could all be displayed, and updated, on a single screen.

• The left side of the screen was for inputs, the right side for outputs.

• The screen is divided into regions for input(2), input display and prompts(1), Beam Cross section(3), Numerical Results(4), and Beam Deflection(5).

5.1.3.2 - Input:

• Current Inputs were indicated by placing a box around the item on the display(1).

• In a separate Prompt Box(2), this input could be made.

• The cursor keys could be used to cursor the input selector up or down.

• Single keystroke operation.

• Keys required: UP/DOWN Cursors, F1, F2, F4, numbers from ‘0’ to ‘9’, ‘.’, ‘-’, and <RETURN>. In the spirit of robustness it was decided to screen all other keys.

5.1.3.3 - Output:

• Equations, calculations, material types, and other relevant information were obtained from a text.

• Proper textual descriptions were used to ensure clarity for the user.

• For a printed report, screen information would be printed to a printer, with the prompt area replaced with the date and time.

5.1.3.4 - Help:

• A special set of help information was needed. It was decided to ensure that the screen always displays all information necessary(2).

5.1.3.5 - Error Checking:

• Reject any input which violates the input limits.

• A default design was given, which the user could modify.

• An error checking program was created, which gives error messages.

5.1.3.6 - Miscellaneous:

• The screen was expressed in normalized coordinates by most sub-routines.

• Colors were used to draw attention, and highlight areas.

5.1.4 Flow Program:

 

5.1.5 Expand Program

• The routines were written in a top down fashion, in a time of about 30 hours. These routines are listed below.

 

• Condition and error flags were used to skip unnecessary operations, and thus speed up response. A response of more than 0.5 seconds will result in loss of attention by the user.

 

5.1.6 Testing and Debugging:

• The testing and debugging was very fast, with only realignment of graphics being required. This took a couple of hours.

5.1.7 Documentation

5.1.7.1 - Users Manual:

• The documentation included an Executive Summary of what the Program does.

• The Objectives of the program were described.

• The theory for beam design was given for the reference of any program user, who wanted to verify the theory, and possible use it.

• A manual was given which described key layouts, screen layout, basic sequence of operations, inputs and outputs.

• Program Specifications were also given.

• A walk through manual was given. This allowed the user to follow an example which displayed all aspects of the program.

5.1.7.2 - Programmers Manual:

• Design Strategy was outlined and given.

• A complete program listing was given (with complete comments).

• Complete production of this Documentation took about 6 hours.

5.1.8 Listing of BeamCAD Program.

• Written for turbo ‘C’

5.2 Problems

Problem 5.1 Draw a simple window based GUI for a plant floor layout viewer. Also describe the functions of the various buttons, windows, etc.

Problem 5.2 You have been asked to design a CAD program which will choose a bolt and a nut to hold two pieces of sheet metal together. Each piece of sheet metal will have a hole drilled in it that is the size of the screw. You are required to consider that the two pieces are experiencing a single force. State your assumptions about the problem, then describe how you would produce this program with a Top Down design.

5.3 Example: Beam CAD

/*

* BeamCAD

*

* By Hugh Jack,

*

* An Automated approach to beam design. This is an interactive program

* Designed to take input about a beam and then determine beam para-

* meters, which are displayed both graphically and numerically.

* After on screen design a hardcopy may be made on an Epson compatible

* printer. The program requires an EGA quality monitor, with an IBM

* PC compatible system.

*

* February, 9th, 1989.

*

*/

 

 

/* header files which define functions and constants */

#include “stdio.h”

#include “graphics.h”

#include “math.h”

#include “time.h”

#include “conio.h”

#include “bios.h”

 

 

/* define internal operation and error codes */

#define DONE -1

#define NO_ERROR 0

#define ERROR 1

#define REVISED 2

#define NEW 3

#define UPDATE 4

#define PRINTER_ERROR 5

 

 

/* define material types */

#define STEEL 0

#define ALUMINUM 1

#define END_MATERIALS 2

 

 

/* define beam types */

#define I_BEAM 0

#define CHANNEL_BEAM 1

#define SOLID_BEAM 2

#define HOLLOW_BEAM 3

#define L_BEAM 4

#define END_BEAMS 5

 

 

/* set corners of user input box */

#define INPUT_LEFT .03

#define INPUT_RIGHT .45

#define INPUT_BOTTOM .97

#define INPUT_TOP .85

 

 

/* miscellaneous definitions */

#define EXTENSION 20 /* standoff for dimensions */

#define DOUBLE_LINE_GAP .005 /* normalized gap between double lines */

#define X_Y_RATIO 1.408 /* Screen x to y aspect ratio */

#define PAGE_OFFSET 80 /* Output offset for printer */

#define ERROR_BIT 8 /* Printer error bit */

 

/* define some key codes */

#define DOWN 1

#define UP -1

#define F_1 59

#define F_3 61

#define F_4 62

#define UP_ARROW 72

#define DOWN_ARROW 80

#define ENTER 13

 

 

/* declare functions in this listing */

void box(),

calculations(),

draw_line(),

kill(),

picture(),

screen(),

text();

int enter(),

input(),

printer(),

printes(),

setup();

 

 

/* set up formats for user inputs, prompts and help prompts */

struct entry { char name[25];

double posx;

double posy;

char help1[40];

char help2[40]; };

 

struct entry list[8] = {{{“Beam Type :”}, .08, .18,

{“1. I-Beam 2. Channel “},

{“3. Solid 4. Hollow 5. L-Beam”}},

{{“Beam Material :”}, .08, .23,

{“1. Steel 2. Aluminum”}},

{{“Beam Thickness :”}, .08, .33,

{“Metal Plat thickness for beam “},

{“Construction”}},

{{“Beam Height :”}, .08, .38,

{“Total height of beam from top to bottom”}},

{{“Beam Width :”}, .08, .43,

{“Total width of beam from left to right”}},

{{“Span Length :”}, .08, .53,

{“Length of unsuported span to be”},

{“considered”}},

{{“Load Position Offset :”}, .08, .58,

{“Distance from left side to the Point”},

{“at which a load force is applied”}},

{{“Load Force :”}, .08, .63,

{“Total load force applied at load”},

{“position”}}};

 

/* set up format and structure for material description */

struct mats { char name[15];

double weight;

double modulus; };

 

struct mats materials[10] = {{{“Steel”}, .283, 10300000.0},

{{“Aluminum”}, .0995, 29000000.0}};

 

 

/* set up work strings and various beam names */

char work[80],

work2[20],

beams[10][20] = {{“I Beam”},

{“Channel Beam”},

{“Solid Beam”},

{“Hollow Beam”},

{“L Beam”}};

 

 

/* set up global integers */

int beam_type = I_BEAM, /* beam cross section type */

beam_material = STEEL, /* beam material used */

entry_number = 0; /* Current choice on input menu */

 

 

/* set up global double precision numbers */

double beam_width = 3.0, /* Width of beam cross section */

beam_height = 6.0, /* Height of Beam cross section */

beam_thick = 0.5, /* Thickness of metal plates */

beam_length = 120.0, /* Length of beam span */

beam_load = 0.0, /* Load force applied to beam */

beam_point = 0.0, /* displacement of applied load */

beam_area, /* calculated cross section area */

x_centroid, /* calculated x centroid */

y_centroid, /* calculated y centroid */

moment_inertia, /* Calculated moment of inertia */

x_axis, /* calculated x principal axis */

y_axis, /* calculated y principal axis */

axial_stiffness, /* calculated axial stiffness */

bending_stiffness, /* calculated bending stiffness */

beam_deflect, /* calculated beam deflection */

deflect_point, /* point of maximum deflection */

out_distance, /* calculated distance from fibres */

beam_weight, /* calculated total beam weight */

xmax, /* absolute width of screen x */

ymax; /* absolute height of screen y */

 

 

main()

/*

* EXECUTIVE CONTROL LEVEL

*

* This is the main terminal point between the various stages of setup,

* input, revision and termination.

*

* January 29th, 1989.

*/

{

static int error;

 

if((error = setup()) != ERROR) {

screen(NEW);

screen(UPDATE);

while((error = input()) != DONE) {

if(error == REVISED) {

screen(NEW);

screen(UPDATE);

}

}

error = NO_ERROR;

}

kill();

if(error == ERROR) {

printf(“EGA Graphics Driver Not Installed”);

}

}

 

 

 

int setup()

/*

* SYSTEM INITIALIZATION

*

* This will initialize an EGA monitor and then initialize, and collect

* video parameters, and initialize the printer.

*

* January 29th, 1989.

*/

{

static int driver,

mode,

error;

 

/* Detect EGA driver and initialize */

detectgraph(&driver, &mode);

error = ERROR;

if(driver == EGA){

error = NO_ERROR;

initgraph(&driver, &mode, ““);

}

 

/* Initialize printer port */

biosprint(1, 7, 0);

 

/* get maximum x and y screen pixel coordinates */

xmax = getmaxx();

ymax = getmaxy();

 

return(error);

}

 

 

 

void screen(int option)

/*

* SCREEN LAYOUT/UPDATE

*

* This section will set up the screen with basic titles and headings.

* The section will also update the current values of beam parameters.

*

* January 29th, 1989.

*/

{

/* If instructed then clear screen and add titles */

if(option == NEW){

/* Clear screen */

cleardevice();

 

/* Add titles and instructions */

draw_line(.50, 0.0, .50, 1.0-DOUBLE_LINE_GAP);

draw_line(.5 + DOUBLE_LINE_GAP, 0.0, .5 + DOUBLE_LINE_GAP, 1.0-DOUBLE_LINE_GAP);

settextstyle(SANS_SERIF_FONT, HORIZ_DIR, 4);

text(.02, .014, “Beam C.A.D.”);

settextstyle(SMALL_FONT, HORIZ_DIR, 6);

text(.31, .06, “by Hugh Jack”);

settextstyle(SMALL_FONT, HORIZ_DIR, 4);

setcolor(GREEN);

text(INPUT_LEFT, INPUT_TOP: .10, “F1: QUIT F3: SCREEN PRINT F4: HARDCOPY”);

text(INPUT_LEFT, INPUT_TOP: .07, “Use UP and DOWN Cursors to select Parameter”);

text(INPUT_LEFT, INPUT_TOP: .04, “enter new paramter and press RETURN to accept”);

setcolor(WHITE);

box(INPUT_LEFT, INPUT_BOTTOM, INPUT_RIGHT, INPUT_TOP, GREEN, NEW);

}

 

/* If instructed then update beam information */

if(option == UPDATE){

/* Calculate new output parameters from input parameters */

calculations();

 

/* Show input data */

text(.05, .13, “Beam”);

sprintf(work, “Type : %s”, beams[beam_type]);

text(.08, .18, work);

sprintf(work, “Material : %s”, materials[beam_material].name);

text(.08, .23, work);

text(.05, .28, “Cross Section”);

sprintf(work, “Thickness : %.3f in.”, beam_thick);

text(.08, .33, work);

sprintf(work, “Height : %.3f in.”, beam_height);

text(.08, .38, work);

sprintf(work, “Width : %.3f in.”, beam_width);

text(.08, .43, work);

text(.05, .48, “Span”);

sprintf(work, “Length : %.3f in.”, beam_length);

text(.08, .53, work);

sprintf(work, “Load Posit.: %.3f in.”, beam_point);

text(.08, .58, work);

sprintf(work, “Load : %.3f lbs.”, beam_load);

text(.08, .63, work);

 

/* Print Calculated Parameters */

sprintf(work, “Beam Cross Sectional Area in^2: %.3f”, beam_area);

text(.56, .55, work);

sprintf(work, “Weight lbs.: %.3f”, beam_weight);

text(.56, .59, work);

sprintf(work, “Axial Stiffness lb. / in: %.3g”, axial_stiffness);

text(.56, .63, work);

sprintf(work, “Bending Stiffness lbs / in^2: %.3g”, bending_stiffness);

text(.56, .67, work);

sprintf(work, “Maximum Beam Deflection in.: %.3g”, beam_deflect);

text(.56, .71, work);

 

/* Draw cross section and loading diagrams */

picture(beam_type);

}

}

 

 

 

void calculations()

/*

* CALCULATE BEAM PARAMETERS

*

* The global values of the beam parameters are use to calculate

* the other output variables of the beam parameters.

*

* February, 9th, 1989.

*/

{

/* locate general centroid */

x_centroid = x_axis = beam_width / 2.0;

y_centroid = y_axis = beam_height / 2.0;

 

/* find moment of inertia for solid beam and later subtract

hollow sections for various beam types. */

moment_inertia = beam_width*beam_height*beam_height*beam_height/12.0;

 

if(beam_type == I_BEAM) {

beam_area = beam_thick*(2*beam_width + beam_height: 2*beam_thick);

moment_inertia = moment_inertia: (beam_width-beam_thick)*pow((beam_height-beam_thick), 3.0)/12.0;

}

 

if(beam_type == CHANNEL_BEAM) {

beam_area = beam_thick*(2*beam_width + beam_height: 2*beam_thick);

x_centroid =(pow(beam_width, 2.0) + (beam_height: 2*beam_thick)*beam_thick)/(beam_width + (beam_height: 2*beam_thick))/2.0;

moment_inertia = moment_inertia: (beam_width-beam_thick)*pow((beam_height-beam_thick), 3.0)/12.0;

}

 

if(beam_type == SOLID_BEAM) {

beam_area = beam_width*beam_height;

}

 

if(beam_type == HOLLOW_BEAM) {

beam_area = beam_thick*(2*beam_width + 2*beam_height: 4*beam_thick);

moment_inertia = moment_inertia: (beam_width: 2*beam_thick)*pow((beam_height-beam_thick), 3.0)/12.0;

}

 

if(beam_type == L_BEAM) {

beam_area = beam_thick*(beam_width + beam_height: beam_thick);

x_centroid = (beam_width*beam_width +(beam_height-beam_thick)*beam_thick)/2.0/(beam_height + beam_width: beam_thick);

y_centroid = (beam_height*beam_height +(beam_width-beam_thick)*beam_thick)/2.0/(beam_height + beam_width: beam_thick);

moment_inertia = (beam_width*pow(y_centroid, 3.0): (beam_width-beam_thick)*pow((y_centroid-beam_thick),3.0)+beam_thick*pow((beam_height-y_centroid), 3.0))/3.0;

}

 

axial_stiffness = beam_area * materials[beam_material].modulus;

bending_stiffness = materials[beam_material].modulus * moment_inertia;

 

beam_weight = beam_area * materials[beam_material].weight * beam_length;

 

/* find deflection of beam under loading */

deflect_point = pow((beam_point*(2 * beam_length-beam_point)/3.0), .5);

beam_deflect = beam_load*(beam_length: beam_point)/(3.0*bending_stiffness*beam_length)*pow(deflect_point, 3);

}

 

 

 

int input()

/*

* INPUT MANAGER

*

* User input functions are handled through this subroutine. These

* functions include numerical input and checking, watching function

* keys, and issuing proper feedback for executive control.

*

* January 28th, 1989.

*/

{

int up_down,

error,

flagger,

count;

double x,

y,

inpoff;

char in;

 

error = 0;

/* set flag for cursor movement */

up_down = 0;

 

/* Do boxes and prompts for current input */

x = list[entry_number].posx;

y = list[entry_number].posy;

box(x-.01, y+.045, x+.30, y-.015, GREEN, NEW);

text(INPUT_LEFT+2*DOUBLE_LINE_GAP, INPUT_TOP+4*DOUBLE_LINE_GAP, list[entry_number].name);

text(INPUT_LEFT+2*DOUBLE_LINE_GAP, INPUT_TOP+.05, list[entry_number].help1);

text(INPUT_LEFT+2*DOUBLE_LINE_GAP, INPUT_TOP+.08, list[entry_number].help2);

inpoff = textwidth(list[entry_number].name)/xmax+.01;

work[0] = 0;

count = 0;

 

/* Loop while numbers are being entered */

setcolor(WHITE+BLINK);

/* cursor marker */

text(INPUT_LEFT+inpoff+(count+1)/100.0, INPUT_TOP+.02, “_”);

setcolor(WHITE);

/* screen for too many chars, and no control keys */

while((count < 12) && ((in = getch()) != ENTER) && (in != 0)) {

if(((in >= ‘0’) && (in <= ‘9’)) || (in == ‘.’) || ((in == ‘-’) && (count == 0))) {

/* update input string */

work[count] = in;

count++;

work[count] = 0;

 

/* update screen input line */

sprintf(work2, “%c”, in);

text(INPUT_LEFT+inpoff+count/100.0, INPUT_TOP+.02, work2);

 

/* Cursor update */

setcolor(WHITE+BLINK);

text(INPUT_LEFT+inpoff+(count+1)/100.0, INPUT_TOP+.02, “_”);

setcolor(WHITE);

setcolor(BLACK);

text(INPUT_LEFT+inpoff+(count)/100.0, INPUT_TOP+.02, “_”);

setcolor(WHITE);

}

/* beep in case of input error */

else { printf(“\007”);}

}

 

/* look for control and cursor keys */

if(in == 0) {

in = getch();

if(in == DOWN_ARROW) up_down = DOWN;

if(in == UP_ARROW) up_down = UP;

if(in == F_1) error = DONE;

if(in == F_3) {

if(printes() == ERROR) {error = PRINTER_ERROR;}

else {error = REVISED;}

}

if(in == F_4) {

if(printer() == ERROR) {error = PRINTER_ERROR;}

else {error = REVISED;}

}

count = 0;

}

 

/* Check for numerical input error */

if((count > 0) && (count < 12)) {

error = enter();

up_down = DOWN;

}

if(count == 12) error = ERROR;

 

/* Clear input box and indicate error if they have occured */

box(x-.01, y+.045, x+.30, y-.015, BLACK, NEW);

box(INPUT_LEFT, INPUT_BOTTOM, INPUT_RIGHT, INPUT_TOP, GREEN, UPDATE);

if((error == ERROR) || (error == PRINTER_ERROR)) {

printf(“\007”);

if(error == ERROR) {

error = ERROR;

text(INPUT_LEFT+2*DOUBLE_LINE_GAP, INPUT_BOTTOM-.05, “INPUT ERROR: (Hit any key to clear)”);

}

if(error == PRINTER_ERROR) {

error = REVISED;

text(INPUT_LEFT+2*DOUBLE_LINE_GAP, INPUT_BOTTOM-.05, “PRINTER ERROR: (Hit any key to clear)”);

}

getch();

box(INPUT_LEFT, INPUT_BOTTOM, INPUT_RIGHT, INPUT_TOP, GREEN, UPDATE);

}

 

/* update to new menu choice */

entry_number = entry_number + up_down;

if(entry_number < 0) entry_number = 7;

if(entry_number > 7) entry_number = 0;

 

return(error);

}

 

 

 

 

int printer()

/* BEAM DUMPER

*

* This routine will prepare the screen and dump it to an EPSON type

* printer. This will not do the printing, but will use the routines

* PRINTES() to do the printing.

*

* February 2nd, 1989.

*/

{

static double xx,yy;

 

/* Do the time sort of thing */

time_t timet;

struct tm *times;

time(&timet);

times = localtime(&timet);

 

/* Clear input boxes on current screen */

xx = list[entry_number].posx;

yy = list[entry_number].posy;

box(xx-.01, yy+.045, xx+.30, yy-.015, BLACK, NEW);

box(INPUT_LEFT-2*DOUBLE_LINE_GAP, INPUT_BOTTOM, INPUT_RIGHT+2*DOUBLE_LINE_GAP, INPUT_TOP-.15, BLUE, UPDATE);

box(INPUT_LEFT-2*DOUBLE_LINE_GAP, INPUT_BOTTOM, INPUT_RIGHT+2*DOUBLE_LINE_GAP, INPUT_TOP-.15, BLACK, NEW);

box(DOUBLE_LINE_GAP, 1: DOUBLE_LINE_GAP, 1: DOUBLE_LINE_GAP, DOUBLE_LINE_GAP, BLUE, NEW);

 

/* Add design date to screen */

text(INPUT_LEFT, INPUT_TOP-.05, “Design Date :”);

text(INPUT_LEFT, INPUT_TOP, asctime(times));

 

return(printes());

}

 

 

 

int printes()

/* SCREEN DUMPER

*

* This routine will copy the screen to an EPSON type

* printer. This will constitute a hard copy output. This routine was

* prepared with the help of a basic routine written by Peter Budgell and

* Bernard Julien. The basic operation is to read a pixel from the

* screen and then print it.

*

* February 2nd, 1989.

*/

{

static int x, y, z, count, bit, error;

 

/* Continue if no error */

if((error = ((int)(biosprint(2, 7, 0)) & ERROR_BIT)) == 0) {

/* Prepare printer */

biosprint(0, 27, 0);

biosprint(0, ‘A’, 0);

biosprint(0, 8, 0);

for(y = 0; y < (int)xmax; y = y + 8) {

biosprint(0, 27, 0);

biosprint(0, ‘L’, 0);

biosprint(0, (int)(2*(ymax+PAGE_OFFSET))%256, 0);

biosprint(0, (int)(2*(ymax+PAGE_OFFSET))/256, 0);

for(x = 0; x < PAGE_OFFSET; x++) {

biosprint(0, 0, 0);

biosprint(0, 0, 0);

}

for(x = (int)ymax; x > 0; x--) {

count = 0;

bit = 1;

for(z = 7; z >= 0; z--) {

count = count + bit*(getpixel(y+z, x) != BLACK);

bit = bit + bit;

}

biosprint(0, count, 0);

biosprint(0, count, 0);

}

biosprint(0, 13, 0);

biosprint(0, 10, 0);

}

error = NO_ERROR;

}

else error = ERROR;

 

return(error);

}

 

 

 

 

int enter()

/*

* ENTRY CHECKER

*

* This routine will use the previous input value to determine input

* validity, and update valid inputs. The value will be taken from

* the WORK string and then considered for the current input.

*

* January 28th, 1989.

*/

{

double f_result;

int i_result,

error;

 

/* Prepare for analysis */

f_result = atof(work);

i_result = atoi(work);

error = ERROR;

 

/* check for no value */

if(work[0] == 0) error = NO_ERROR;

 

if(error == ERROR) {

/* Update beam type */

if((entry_number == 0) && (i_result > 0) && (i_result < L_BEAM+2)) {

error = NO_ERROR;

if(beam_type != i_result-1) error = REVISED;

beam_type = i_result-1;

}

 

if((entry_number == 1) && (i_result > 0) && (i_result < ALUMINUM+2)) {

error = NO_ERROR;

if(beam_material != i_result-1) error = REVISED;

beam_material = i_result-1;

}

 

if((entry_number == 2) && (f_result > 0.025) && (f_result < beam_width/2) && (f_result < beam_height/2)) {

error = NO_ERROR;

if(beam_thick != f_result) error = REVISED;

beam_thick = f_result;

}

 

if((entry_number == 3) && (f_result > beam_thick*2.0) && (f_result < 60.0)) {

error = NO_ERROR;

if(beam_height != f_result) error = REVISED;

beam_height = f_result;

}

 

if((entry_number == 4) && (f_result > beam_thick/2.0) && (f_result < 60.0)) {

error = NO_ERROR;

if(beam_width != f_result) error = REVISED;

beam_width = f_result;

}

 

if((entry_number == 5) && (f_result > 0.0) && (f_result < 200.0) && (f_result >= beam_point)) {

error = NO_ERROR;

if(beam_length != f_result) error = REVISED;

beam_length = f_result;

}

 

if((entry_number == 6) && (f_result >= 0.0) && (f_result <= beam_length)) {

error = NO_ERROR;

if(beam_point != f_result) error = REVISED;

beam_point = f_result;

}

 

if((entry_number == 7) && (abs(f_result) < 10000000.0)) {

error = NO_ERROR;

if(beam_load != f_result) error = REVISED;

beam_load = f_result;

}

 

}

return(error);

}

 

 

 

 

void text(double x, double y, char *text)

/*

* Text Utility

*

* A routine to make text statements more readable, by allowing entry in

* normalized coordinates.

*

* January 28th, 1989.

*/

{

outtextxy(x * xmax, y * ymax, text);

}

 

 

 

 

 

void draw_line(double x1, double y1, double x2, double y2)

/*

* Line Utility

*

* A routine to simplify line statements by allowing normalized calls.

*

* January 30th, 1989.

*/

{

line((int)(x1*xmax), (int)(y1*ymax), (int)(x2*xmax), (int)(y2*ymax));

}

 

 

 

 

 

void box(double x1, double y1, double x2, double y2, int color, int refresh)

/*

* Box Drawer

*

* This routine will simply draw a box with double lines , or erase

* the contents.

*

* January 28th, 1989.

*/

{

int temp_color;

temp_color = getcolor();

setcolor(color);

 

/* Draw outer box */

draw_line(x1, y1, x2, y1);

draw_line(x2, y1, x2, y2);

draw_line(x2, y2, x1, y2);

draw_line(x1, y2, x1, y1);

 

/* Draw inner box */

draw_line(x1 + DOUBLE_LINE_GAP, y1: DOUBLE_LINE_GAP, x2: DOUBLE_LINE_GAP, y1: DOUBLE_LINE_GAP);

draw_line(x2: DOUBLE_LINE_GAP, y1: DOUBLE_LINE_GAP, x2: DOUBLE_LINE_GAP, y2 + DOUBLE_LINE_GAP);

draw_line(x2: DOUBLE_LINE_GAP, y2 + DOUBLE_LINE_GAP, x1 + DOUBLE_LINE_GAP, y2 + DOUBLE_LINE_GAP);

draw_line(x1 + DOUBLE_LINE_GAP, y2 + DOUBLE_LINE_GAP, x1 + DOUBLE_LINE_GAP, y1: DOUBLE_LINE_GAP);

 

/* Erase box contents if flag set */

if(refresh == UPDATE) {

setfillstyle(SOLID_FILL, BLACK);

floodfill((int)(((x2 + x1)/2.0)*xmax), (int)(((y1 + y2)/2.0) * ymax), color);

}

 

setcolor(temp_color);

}

 

 

 

 

void picture(int draw_beam)

/*

* Beam Drawer

*

* This section will produce all beam graphics and dimensions

*

* January 30th, 1989.

*/

{

static int x_s,

x_e,

y_s,

y_e,

cx1,

cx2,

cx3,

cx4,

cx5,

cx6,

cy1,

cy2,

cy3,

cy4,

cy5,

cy6,

x_offset,

y_offset,

x_c_offset,

y_c_offset;

static double scale_x,

scale_y,

px,

py,

de,

offset;

 

x_s = xmax/2 + 3*EXTENSION + 40;

y_s = ymax/2: 15;

x_e = xmax: 5;

y_e = 22 + EXTENSION;

if(x_axis != x_centroid) y_e = y_e + EXTENSION;

if(y_axis == y_centroid) x_s = xmax/2 + 2*EXTENSION + 40;

if(beam_width < beam_height){

scale_x = (x_e: x_s) / beam_height / X_Y_RATIO;

scale_y = (y_e: y_s) / beam_height;

};

if(beam_width >= beam_height){

scale_x = (x_e: x_s) / beam_width / X_Y_RATIO;

scale_y = (y_e: y_s) / beam_width;

};

 

cx1 = x_s;

cx2 = x_s + (int)(scale_x * beam_thick);

cx3 = x_s + (int)(scale_x * (beam_width: beam_thick) / 2);

cx4 = x_s + (int)(scale_x * (beam_width + beam_thick) / 2);

cx5 = x_s + (int)(scale_x * (beam_width: beam_thick));

cx6 = x_s + (int)(scale_x * beam_width);

 

cy1 = y_s;

cy2 = y_s + (int)(scale_y * beam_thick);

cy3 = y_s + (int)(scale_y * (beam_height: beam_thick) / 2);

cy4 = y_s + (int)(scale_y * (beam_height + beam_thick) / 2);

cy5 = y_s + (int)(scale_y * (beam_height: beam_thick));

cy6 = y_s + (int)(scale_y * beam_height);

 

x_c_offset = cx1 + scale_x * x_centroid;

y_c_offset = cy1 + scale_y * y_centroid;

x_offset = cx1 + scale_x * x_axis;

y_offset = cy1 + scale_y * y_axis;

 

setcolor(WHITE);

 

/* Title for cross section */

if(x_axis != x_centroid)

{outtextxy(cx1: EXTENSION, cy6: 2*EXTENSION-15, “BEAM CROSS SECTION”);}

else {outtextxy(cx1: EXTENSION, cy6: EXTENSION-15, “BEAM CROSS SECTION”);}

 

/* Title for beam deflection */

text(.54, .76, “EXAGERATED BEAM DEFLECTION (simple supports)”);

 

setcolor(CYAN);

if(draw_beam == I_BEAM) {

moveto(cx1, cy1);

lineto(cx6, cy1);

lineto(cx6, cy2);

lineto(cx4, cy2);

lineto(cx4, cy5);

lineto(cx6, cy5);

lineto(cx6, cy6);

lineto(cx1, cy6);

lineto(cx1, cy5);

lineto(cx3, cy5);

lineto(cx3, cy2);

lineto(cx1, cy2);

lineto(cx1, cy1);

}

 

if(draw_beam == CHANNEL_BEAM) {

moveto(cx1, cy1);

lineto(cx6, cy1);

lineto(cx6, cy2);

lineto(cx2, cy2);

lineto(cx2, cy5);

lineto(cx6, cy5);

lineto(cx6, cy6);

lineto(cx1, cy6);

lineto(cx1, cy1);

}

 

if(draw_beam == SOLID_BEAM) {

moveto(cx1, cy1);

lineto(cx1, cy6);

lineto(cx6, cy6);

lineto(cx6, cy1);

lineto(cx1, cy1);

}

 

if(draw_beam == HOLLOW_BEAM) {

moveto(cx1, cy1);

lineto(cx6, cy1);

lineto(cx6, cy6);

lineto(cx1, cy6);

lineto(cx1, cy1);

moveto(cx2, cy2);

lineto(cx2, cy5);

lineto(cx5, cy5);

lineto(cx5, cy2);

lineto(cx2, cy2);

}

 

if(draw_beam == L_BEAM) {

moveto(cx1, cy1);

lineto(cx6, cy1);

lineto(cx6, cy2);

lineto(cx2, cy2);

lineto(cx2, cy6);

lineto(cx1, cy6);

lineto(cx1, cy1);

}

 

/* Draw beam for bending display */

line((int)(.60*xmax), (int)(.90*ymax), (int)(.60*xmax), (int)(.88*ymax));

line((int)(.90*xmax), (int)(.90*ymax), (int)(.90*xmax), (int)(.88*ymax));

if(fabs(beam_deflect/beam_length) > 0.00001) {

de = beam_length/6.0*beam_deflect/fabs(beam_deflect);

for(px = 0.0; px <= deflect_point; px = px + beam_length/200){

py = ((de-de*pow(((deflect_point -px)/deflect_point), 2.0))/beam_length) * (.1) + .88;

putpixel((int)((.6+px/beam_length*.3)*xmax), (int)(py*ymax), CYAN);

putpixel((int)((.6+px/beam_length*.3)*xmax), (int)((py+.02)*ymax), CYAN);

}

for(px = deflect_point; px <= beam_length; px = px + beam_length/200){

py = ((de-de*pow(((px-deflect_point)/(beam_length: deflect_point)), 2.0))/beam_length) * (.1) + .88;

putpixel((int)((.6+px/beam_length*.3)*xmax), (int)(py*ymax), CYAN);

putpixel((int)((.6+px/beam_length*.3)*xmax), (int)((py+.02)*ymax), CYAN);

}

}

else {

line((int)(.60*xmax), (int)(.90*ymax), (int)(.90*xmax), (int)(.90*ymax));

line((int)(.60*xmax), (int)(.88*ymax), (int)(.90*xmax), (int)(.88*ymax));

}

 

/* Fill Beam Cross section if thick enough */

setfillstyle(LTSLASH_FILL, 7+beam_material);

if(((cx2-cx1) > 2) && ((cy1: cy2) > 2)){

floodfill(cx1 + 1, cy1: 1, CYAN);

floodfill(cx1 + 1, cy6 + 1, CYAN);

}

 

setcolor(RED);

 

/* Beam Length Dimension */

line(xmax*.60, ymax*.90 + 3, xmax*.60, ymax*.90 + EXTENSION);

line(xmax*.90, ymax*.90 + 3, xmax*.90, ymax*.90 + EXTENSION);

line(xmax*.60, ymax*.90 + 10, xmax*.90, ymax*.90 + 10);

sprintf(work, “%.3f in.”, beam_length);

text(.61, .94, work);

 

/* Force Position Location */

offset = .30 * (beam_point / beam_length) + .60;

line(xmax*.6, ymax*.88: 3, xmax*.6, ymax*.88: EXTENSION);

line(xmax*offset, ymax*.88: 3, xmax*offset, ymax*.88: EXTENSION);

line(xmax*.6, ymax*.88: 10, xmax*offset, ymax*.88: 10);

line(xmax*offset, ymax*.88: 3, xmax*offset -3, ymax*.88: 8);

line(xmax*offset, ymax*.88: 3, xmax*offset +3, ymax*.88: 8);

sprintf(work, “%.3f in.”, beam_point);

text(offset+.01, .84, work);

sprintf(work, “%.3f lb.”, beam_load);

text(offset, .79, work);

 

 

/* Beam Width Dimension */

line(cx1, cy1+3, cx1, cy1 + EXTENSION);

line(cx6, cy1+3, cx6, cy1 + EXTENSION);

line(cx1, cy1 + 10, cx6, cy1 + 10);

sprintf(work, “%.3f in.”, beam_width);

outtextxy(cx1 + 10, cy1+15, work);

 

/* Height and Thickness Dimensions */

settextstyle(SMALL_FONT, VERT_DIR, 4);

line(cx6+3, cy1, cx6+EXTENSION, cy1);

line(cx6+3, cy6, cx6+EXTENSION, cy6);

line(cx6+10, cy1, cx6+10, cy6);

sprintf(work, “%.3f in.”, beam_height);

outtextxy(cx6 + EXTENSION, cy1-10-textwidth(work), work);

 

/* Draw Thickness Dimension for all but solid beam */

if(beam_type != SOLID_BEAM) {

line(cx1-EXTENSION, cy1, cx1-3, cy1);

line(cx1-EXTENSION, cy2, cx1-3, cy2);

line(cx1-10, cy1, cx1-10, cy1+15);

line(cx1-10, cy2, cx1-10, cy2-15);

sprintf(work, “%.3f in.”, beam_thick);

outtextxy(cx1-15, cy2-10-textwidth(work), work);

}

 

/* Principal and centroid y axis dimensions */

line(cx1-EXTENSION, cy1, cx1-2*EXTENSION, cy1);

line(cx1-EXTENSION-3, y_offset, cx1-2*EXTENSION, y_offset);

line(cx1-EXTENSION-10, cy1, cx1-EXTENSION-10, cy1+15);

line(cx1-EXTENSION-10, y_offset, cx1-EXTENSION-10, y_offset-15);

sprintf(work, “%.3f in.”, y_axis);

outtextxy(cx1-EXTENSION-15, y_offset-10-textwidth(work), work);

if(y_axis != y_centroid) {

line(cx1-2*EXTENSION, cy1, cx1-3*EXTENSION, cy1);

line(cx1-2*EXTENSION-3, y_c_offset, cx1-3*EXTENSION, y_c_offset);

line(cx1-2*EXTENSION-10, cy1, cx1-2*EXTENSION-10, cy1+15);

line(cx1-2*EXTENSION-10, y_c_offset, cx1-2*EXTENSION-10, y_c_offset-15);

sprintf(work, “%.3f in.”, y_centroid);

outtextxy(cx1-2*EXTENSION-15, y_c_offset-10-textwidth(work), work);

}

 

settextstyle(SMALL_FONT, HORIZ_DIR, 4);

 

/* Principal and centroid x axis dimensions */

line(cx1, cy6-3, cx1, cy6: EXTENSION);

line(x_offset, cy6-3, x_offset, cy6-EXTENSION);

line(cx1-EXTENSION, cy6-10, cx1, cy6-10);

line(x_offset, cy6-10, x_offset+EXTENSION, cy6-10);

sprintf(work, “%.3f in.”, x_axis);

outtextxy(x_offset + 10, cy6-EXTENSION, work);

if(x_axis != x_centroid) {

line(cx1, cy6-EXTENSION-3, cx1, cy6: 2*EXTENSION);

line(x_c_offset, cy6-EXTENSION-3, x_c_offset, cy6: 2*EXTENSION);

line(cx1-EXTENSION, cy6-EXTENSION-10, cx1, cy6-EXTENSION-10);

line(x_c_offset, cy6-EXTENSION-10, x_c_offset+EXTENSION, cy6-EXTENSION-10);

sprintf(work, “%.3f in.”, x_centroid);

outtextxy(x_c_offset + 10, cy6: 2*EXTENSION, work);

}

 

/* Draw Center Line */

setcolor(YELLOW);

setlinestyle(CENTER_LINE, 0, NORM_WIDTH);

line(x_offset, cy1+5, x_offset, cy6-5);

line(cx1-5, y_offset, cx6+5, y_offset);

 

/* Draw Centroid Line */

setcolor(MAGENTA);

setlinestyle(DASHED_LINE, 0, NORM_WIDTH);

line(x_c_offset, cy1+5, x_c_offset, cy6-5);

line(cx1-5, y_c_offset, cx6+5, y_c_offset);

setlinestyle(SOLID_LINE, 0, NORM_WIDTH);

 

/* Restore original Color */

setcolor(WHITE);

 

}

 

 

 

void kill()

/*

* Close Graphics Routines

*

* This will deinitialize the graphics routines initialized earlier.

*

* January 20th, 1989.

*/

{

closegraph();

}

?