/* * ACE/gredit - 2d finite element grid generation * * Paul J. Turner and Antonio M. Baptista * * Copyright 1990-2003 Oregon Health and Science University * All Rights Reserved. * */ /* * * operations on objects (strings, lines, and boxes) * */ #ifndef lint static char RCSid[] = "$Id: objutils.c,v 1.3 2007/02/21 00:21:21 pturner Exp $"; #endif #include #include #include #include "defines.h" #include "globals.h" #include "graphics.h" double xconv(), yconv(); static int cg = 0; void get_graph_box(int i, boxtype * b) { memcpy(b, &boxes[i], sizeof(boxtype)); } void get_graph_line(int i, linetype * l) { memcpy(l, &lines[i], sizeof(linetype)); } void get_graph_string(int i, plotstr * s) { memcpy(s, &pstr[i], sizeof(plotstr)); } /* * find the nearest object to (x,y) */ void find_item(int gno, double x, double y, int *type, int *numb) { int i; double tmp, xtmp1, ytmp1, xtmp2, ytmp2, m = 1e307; double dx, dy; boxtype box; linetype line; plotstr str; x = xconv(x); y = yconv(y); *type = -1; for (i = 0; i < MAXBOXES; i++) { get_graph_box(i, &box); if (isactive_box(i)) { if (box.loctype == VIEW) { xtmp1 = box.x1; ytmp1 = box.y1; xtmp2 = box.x2; ytmp2 = box.y2; } else { if (gno == box.gno) { xtmp1 = xconv(box.x1); ytmp1 = yconv(box.y1); xtmp2 = xconv(box.x2); ytmp2 = yconv(box.y2); } else { continue; } } tmp = hypot((x - xtmp1), (y - ytmp1)); if (m > tmp) { *type = BOX; *numb = i; m = tmp; } tmp = hypot((x - xtmp1), (y - ytmp2)); if (m > tmp) { *type = BOX; *numb = i; m = tmp; } tmp = hypot((x - xtmp2), (y - ytmp1)); if (m > tmp) { *type = BOX; *numb = i; m = tmp; } tmp = hypot((x - xtmp2), (y - ytmp2)); if (m > tmp) { *type = BOX; *numb = i; m = tmp; } } } for (i = 0; i < MAXLINES; i++) { get_graph_line(i, &line); if (isactive_line(i)) { if (line.loctype == VIEW) { xtmp1 = line.x1; ytmp1 = line.y1; xtmp2 = line.x2; ytmp2 = line.y2; } else { if (gno == line.gno) { xtmp1 = xconv(line.x1); ytmp1 = yconv(line.y1); xtmp2 = xconv(line.x2); ytmp2 = yconv(line.y2); } else { continue; } } tmp = hypot((x - xtmp1), (y - ytmp1)); if (m > tmp) { *type = LINE; *numb = i; m = tmp; } tmp = hypot((x - xtmp2), (y - ytmp2)); if (m > tmp) { *type = LINE; *numb = i; m = tmp; } } } for (i = 0; i < MAXSTR; i++) { get_graph_string(i, &str); if (isactive_string(i)) { if (str.loctype == VIEW) { xtmp1 = str.x; ytmp1 = str.y; } else { if (gno == str.gno) { xtmp1 = xconv(str.x); ytmp1 = yconv(str.y); } else { continue; } } tmp = hypot((x - xtmp1), (y - ytmp1)); if (m > tmp) { *type = STRING; *numb = i; m = tmp; } } } } int isactive_line(int lineno) { if (0 <= lineno && lineno < MAXLINES) return (lines[lineno].active == ON); return (0); } int isactive_box(int boxno) { if (0 <= boxno && boxno < MAXBOXES) return (boxes[boxno].active == ON); return (0); } int isactive_string(int strno) { if (0 <= strno && strno < MAXSTR) return ((pstr[strno].active == ON && pstr[strno].s[0]) || (pstr[strno].active == ON && pstr[strno].type == 1)); return (0); } int next_line(void) { int i; for (i = 0; i < MAXLINES; i++) { if (!isactive_line(i)) { lines[i].active = ON; return (i); } } errwin("Error - no lines available"); return (-1); } int next_box(void) { int i; for (i = 0; i < MAXBOXES; i++) { if (!isactive_box(i)) { boxes[i].active = ON; return (i); } } errwin("Error - no boxes available"); return (-1); } int next_string(void) { int i; for (i = 0; i < MAXSTR; i++) { if (!isactive_string(i)) { return (i); } } errwin("Error - no strings available"); return (-1); } void kill_box(int boxno) { boxes[boxno].active = OFF; } void kill_line(int lineno) { lines[lineno].active = OFF; } void kill_string(int stringno) { pstr[stringno].active = OFF; pstr[stringno].type = 0; pstr[stringno].s[0] = 0; } void do_boxes_proc(void) { set_action(0); set_action(MAKE_BOX_1ST); } void do_lines_proc(void) { set_action(0); set_action(MAKE_LINE_1ST); } void do_move_proc(void) { set_action(0); set_action(MOVE_OBJECT_1ST); } void do_delete_object_proc(void) { set_action(0); set_action(DEL_OBJECT); } void edit_objects_proc(void) { set_action(0); set_action(EDIT_OBJECT); } int define_string(char *s, double wx, double wy) { int i; i = next_string(); if (i >= 0) { if (s != NULL) { strcpy(pstr[i].s, s); } else { pstr[i].s[0] = 0; pstr[i].active = OFF; } pstr[i].font = string_font; pstr[i].color = string_color; pstr[i].linew = string_linew; pstr[i].rot = string_rot; pstr[i].charsize = string_size; pstr[i].loctype = string_loctype; pstr[i].just = string_just; pstr[i].type = 0; pstr[i].sym = string_sym; pstr[i].active = ON; if (string_loctype == VIEW) { pstr[i].x = xconv(wx); pstr[i].y = yconv(wy); pstr[i].gno = -1; } else { pstr[i].x = wx; pstr[i].y = wy; pstr[i].gno = cg; } return i; } return -1; } int define_depth_label(int gridno, int el, double wx, double wy) { int i; i = next_string(); if (i >= 0) { pstr[i].font = string_font; pstr[i].color = string_color; pstr[i].linew = string_linew; pstr[i].rot = string_rot; pstr[i].charsize = string_size; pstr[i].loctype = string_loctype; pstr[i].just = string_just; pstr[i].active = ON; pstr[i].type = 1; pstr[i].sym = string_sym; pstr[i].symsize = string_symsize; pstr[i].x = wx; pstr[i].y = wy; pstr[i].gno = gridno; pstr[i].el = el; return i; } return -1; } void strings_loc_proc(void) { set_action(0); set_action(STR_LOC); } void strings_depth_proc(void) { set_action(0); set_action(PLACE_ISOLINE_LABEL); } void strings_ang_proc(void) { set_action(0); set_action(STR_LOC1ST); } void strings_edit_proc(void) { set_action(0); set_action(STR_EDIT); } void do_clear_lines(void) { int i; for (i = 0; i < MAXLINES; i++) { kill_line(i); } } void do_clear_boxes(void) { int i; for (i = 0; i < MAXBOXES; i++) { kill_box(i); } } void do_clear_text(void) { int i; for (i = 0; i < MAXSTR; i++) { kill_string(i); } } /* * draw annotative text */ void draw_string(int gno, int i) { double xtmp1, ytmp1; int f, c, w, tmpind; double s, d; plotstr pstr; double get_depth_element(); get_graph_string(i, &pstr); if (pstr.type == 1) { if (gno == -1) return; find_element(pstr.gno, pstr.x, pstr.y, &tmpind); if (tmpind >= 0) { d = get_depth_element(pstr.gno, tmpind, pstr.x, pstr.y); } else { return; } if (pstr.sym) { sprintf(pstr.s, " %.*lf", string_prec, d); } else { sprintf(pstr.s, "%.*lf", string_prec, d); } } else { if (gno != -2) { if (pstr.loctype == WORLD && pstr.gno != gno) { return; } if (pstr.loctype == VIEW && gno != -1) { return; } } } if (strlen(pstr.s) && (pstr.charsize > 0.0) && (pstr.active == ON)) { c = setcolor(pstr.color); w = setlinewidth(pstr.linew); (void) setlinestyle(1); s = setcharsize(pstr.charsize); f = setfont(pstr.font); if (pstr.loctype == WORLD) { writestr(pstr.x, pstr.y, pstr.rot, pstr.just, pstr.s); } else { view2world(pstr.x, pstr.y, &xtmp1, &ytmp1); writestr(xtmp1, ytmp1, pstr.rot, pstr.just, pstr.s); } if (pstr.type == 1 && pstr.sym > 0) { my_circlefilled(pstr.x, pstr.y); } (void) setcolor(c); (void) setlinewidth(w); (void) setlinestyle(1); (void) setcharsize(s); (void) setfont(f); } } /* * draw annotative boxes */ void draw_box(int gno, int i) { double xtmp1, ytmp1; double xtmp2, ytmp2; int c, l, w; boxtype b; get_graph_box(i, &b); if (gno != -2) { if (b.loctype == WORLD && b.gno != gno) { return; } if (b.loctype == VIEW && gno != -1) { return; } } if (b.active == ON) { setclipping(0); if (b.fill == COLOR) { c = setcolor(b.fillcolor); if (b.loctype == WORLD) { fillrectcolor(b.x1, b.y1, b.x2, b.y2); } else { view2world(b.x1, b.y1, &xtmp1, &ytmp1); view2world(b.x2, b.y2, &xtmp2, &ytmp2); fillrectcolor(xtmp1, ytmp1, xtmp2, ytmp2); } setcolor(c); } else if (b.fill == PATTERN) { c = setpattern(b.fillpattern); if (b.loctype == WORLD) { fillrectpat(b.x1, b.y1, b.x2, b.y2); } else { view2world(b.x1, b.y1, &xtmp1, &ytmp1); view2world(b.x2, b.y2, &xtmp2, &ytmp2); fillrectpat(xtmp1, ytmp1, xtmp2, ytmp2); } } c = setcolor(b.color); l = setlinestyle(b.lines); w = setlinewidth(b.linew); if (b.loctype == WORLD) { rect(b.x1, b.y1, b.x2, b.y2); } else { view2world(b.x1, b.y1, &xtmp1, &ytmp1); view2world(b.x2, b.y2, &xtmp2, &ytmp2); rect(xtmp1, ytmp1, xtmp2, ytmp2); } setclipping(1); setcolor(c); setlinewidth(w); setlinestyle(l); } } /* * draw annotative lines */ void draw_line(int gno, int i) { double xtmp1, ytmp1; double xtmp2, ytmp2; int c, ll, w; linetype l; get_graph_line(i, &l); if (gno != -2) { if (l.loctype == WORLD && l.gno != gno) { return; } if (l.loctype == VIEW && gno != -1) { return; } } if (l.active == ON) { setclipping(0); c = setcolor(l.color); ll = setlinestyle(l.lines); w = setlinewidth(l.linew); if (l.loctype == WORLD) { draw_arrow(l.x1, l.y1, l.x2, l.y2, l.arrow, l.asize, l.atype); } else { view2world(l.x1, l.y1, &xtmp1, &ytmp1); view2world(l.x2, l.y2, &xtmp2, &ytmp2); draw_arrow(xtmp1, ytmp1, xtmp2, ytmp2, l.arrow, l.asize, l.atype); } setclipping(1); setcolor(c); setlinewidth(w); setlinestyle(ll); } } void draw_annotation(int gno) { int i; setclipping(0); /* shut down clipping for strings, boxes, * lines, and legends */ for (i = 0; i < MAXBOXES; i++) { if (isactive_box(i)) { draw_box(gno, i); } } for (i = 0; i < MAXLINES; i++) { if (isactive_line(i)) { draw_line(gno, i); } } for (i = 0; i < MAXSTR; i++) { if (isactive_string(i)) { if (debuglevel == 5) { printf("String %d\n", i); } draw_string(gno, i); } } setclipping(1); }