coords* coords_new( int img_width, int img_height, double init_cx, double init_cy, double init_size) { coords* c = malloc(sizeof(*c)); if (!c) return 0; c->precision = 0; c->precision = DEFAULT_PRECISION; mpfr_init2(c->xmin, c->precision); mpfr_init2(c->xmax, c->precision); mpfr_init2(c->ymin, c->precision); mpfr_init2(c->ymax, c->precision); mpfr_init2(c->width, c->precision); mpfr_init2(c->height, c->precision); mpfr_init2(c->cx, c->precision); mpfr_init2(c->cy, c->precision); mpfr_init2(c->_size, c->precision); coords_set(c, img_width, img_height); c->init_cx = init_cx; c->init_cy = init_cy; c->init_size = init_size; mpfr_set_d( c->_size, init_size, GMP_RNDN); return c; }
// off_intersectPoly *********************************************************** //gives the intersection vertex between ray [a,b) and polygon p and its parametric value on (a b) //based on http://geometryalgorithms.com/Archive/algorithm_0105/algorithm_0105.htm int off_intersectPoly(intersection *inter, Coords a, Coords b, polygon p) { //direction vector of [a,b] Coords dir = {b.x-a.x, b.y-a.y, b.z-a.z}; //the normal vector to the polygon Coords normale=p.normal; //off_normal(&normale, p); done at the init stage //direction vector from a to a vertex of the polygon Coords w0 = {a.x-p.p[0], a.y-p.p[1], a.z-p.p[2]}; //scalar product MCNUM nw0 =-scalar_prod(normale.x,normale.y,normale.z,w0.x,w0.y,w0.z); MCNUM ndir = scalar_prod(normale.x,normale.y,normale.z,dir.x,dir.y,dir.z); inter->time = inter->edge = inter->in_out=0; inter->v = inter->normal = coords_set(0,0,1); if (fabs(ndir) < EPSILON) // ray is parallel to polygon plane { if (nw0 == 0) // ray lies in polygon plane (infinite number of solution) return 0; else return 0; // ray disjoint from plane (no solution) } // get intersect point of ray with polygon plane inter->time = nw0 / ndir; //parametric value the point on line (a,b) inter->v = coords_set(a.x + inter->time * dir.x,// intersect point of ray and plane a.y + inter->time * dir.y, a.z + inter->time * dir.z); int res=off_pnpoly(p,inter->v); inter->edge=(res==-1); if (ndir<0) inter->in_out=1; //the negative dot product means we enter the surface else inter->in_out=-1; inter->normal=p.normal; return res; //true if the intersection point lies inside the poly } /* off_intersectPoly */
gboolean mouse_clicked(GtkWidget *widget, GdkEventButton *event) { // Handle click event on canvas int index; double coordx, coordy; select_t *select = NULL; // Length from click location to nearest dot mouse_discarded = 0; if (event->button == 8) { // back button if (event->state == GDK_SHIFT_MASK) set_prev_count(); else if (event->state == GDK_CONTROL_MASK) set_first(); else set_prev(); fldstate.mouse_clicked = 0x0; } else if (event->button == 9) { // forward button if (event->state == GDK_SHIFT_MASK) set_next_count(); else if (event->state == GDK_CONTROL_MASK) set_last(); else set_next(); fldstate.mouse_clicked = 0x0; } else if (event->button == 1) { fldstate.mouse_clicked = 0x1; mouse_clickx = event->x; mouse_clicky = event->y; pixel_to_field(&mouse_clickx, &mouse_clicky); fldstate.mouse_clickx = mouse_clickx; fldstate.mouse_clicky = mouse_clicky; switch(mouse_currentMode) { case SELECTONE: // select 1 performer select = field_get_in_area(mouse_clickx, mouse_clicky); if (event->state == GDK_CONTROL_MASK) { // ctrl-click select_toggle_multiple(pstate.select, select); } else if ((event->state & ~GDK_SHIFT_MASK)== 0) { // regular click if (select_empty(select)) { //select_dots_discard(); select_clear(pstate.select); mouse_discarded = 1; break; } index = select_get_form(select); if (!select_form_empty(select) && !select_check_form(pstate.select, index)) { // select form with ability to scale form select_clear(pstate.select); mouse_discarded = 1; select_add_form(pstate.select, select_get_form(select)); select_update_center(pstate.select); } else if (select_form_empty(select) && isSelected(select_get_dot(select)) != 1) { // dot is not selected select_clear(pstate.select); mouse_discarded = 1; if ((index = select_get_dot(select))!= -1) { select_add_dot(pstate.select, index); } } else { // hold click; dots being moved fldstate.mouse_clicked |= 0x2; } } dr_canvas_refresh(drill); break; case ADDPERF: // Add performers by clicking on canvas coordx = event->x; coordy = event->y; pixel_to_field(&coordx, &coordy); index = perf_add(); //coords_set_coord(pshow, index, coordx, coordy); coords_set(pshow->sets->currset->coords[index], coordx, coordy); dr_canvas_refresh(drill); break; case ADDFORM: break; } } else fldstate.mouse_clicked = 0; return TRUE; }
int open_file(char *filename) { // open a file (for now, just save_file) // loop vars int i, j; // file pointer FILE *fp; // stream string char *buffer; // data storage char *data; // operation storage char *operation; // name storage char *name; // info storage char *info; // performer storage char *perfnum_buffer; // performer number int perfnum; // exit code int excode; // sizing for allocation int size; // finished flag int done; // placeholder for char int index; // coord number int cnum; // coordinates double x, y; // new operation char *op; // Structures // performer structures perf_t **perfs; perf_t *perf; // Set structure set_t *currset; // open file for reading if (!filename) return -1; if (!(fp = fopen(filename,"r"))) return -1; // check for valid file excode = file_getValidLine(fp, &buffer); if (strcmp(buffer, "#drillwriter")) { // not a valid save file return -1; } free(buffer); // get the name excode = file_getValidLine(fp, &buffer); size = strlen(buffer); name = (char*)malloc((size+2)*sizeof(char)); if (!name) return -1; strncpy(name, buffer, size+1); excode = file_linetoOps(name, &op, '='); free(op); free(buffer); // store name free(pshow->showname); pshow->showname = (char*)malloc((strlen(name)+1)*sizeof(char)); if (!pshow->showname) return -1; strcpy(pshow->showname, name); free(name); // get info excode = file_getValidLine(fp, &buffer); size = strlen(buffer); info = (char*)malloc((size+2)*sizeof(char)); if (!info) return -1; strncpy(info, buffer, size+1); excode = file_linetoOps(info, &op, '='); free(op); free(buffer); // store info free(pshow->showinfo); pshow->showinfo = (char*)malloc((strlen(info)+1)*sizeof(char)); if (!pshow->showinfo) return -1; strcpy(pshow->showinfo, info); free(info); // get perfnum excode = file_getValidLine(fp, &buffer); size = strlen(buffer); perfnum_buffer = (char*)malloc((size+2)*sizeof(char)); if (!perfnum_buffer) return -1; strncpy(perfnum_buffer, buffer, size+1); excode = file_linetoOps(perfnum_buffer, &op, '='); free(op); free(buffer); perfnum = atoi(perfnum_buffer); free(perfnum_buffer); // make the show show_destroy(&pshow); excode = show_construct(&pshow, perfnum); //printf("perfnum = %i\n", perfnum); // build performers buffer = (char*)malloc(sizeof(char)); if (!buffer) return -1; // get performer info perfs = pshow->perfs; perf = perfs[0]; done = 0; i = -1; do { if (i != -1) { if (perfs[i]) perf = perfs[i]; else exit(-1); } // grab performer pieces free(buffer); // get a valid line excode = file_getValidLine(fp, &buffer); size = strlen(buffer); // get operations at data from line data = (char*)malloc((size+2)*sizeof(char)); if (!data) return -1; strncpy(data, buffer, size+1); excode = file_linetoOps(data, &operation, '='); // interpret data based on operation if (!strcmp(operation, "index")) { // info perf->index = atoi(data); i++; } else if (!strcmp(operation, "symbol")) { // symbol free(perf->symbol); perf->symbol = (char*)malloc((size+1)*sizeof(char)); if (!perf->symbol) return -1; strcpy(perf->symbol, data); } else if (!strcmp(operation, "valid")) { // validity flag perf->valid = atoi(data); } else if (!strcmp(operation, "sets:")) { // moving to coords. finished with perfs done = 1; } free(data); free(operation); } while (done == 0); for (i=i+1; i<perfnum; i++) perfs[i]->valid = 0; // go to first set set_first(); currset = pshow->sets->currset; // get set information do { free(buffer); excode = file_getValidLine(fp, &buffer); //printf("buffer = %s\n", buffer); size = strlen(buffer); data = (char*)malloc((size+2)*sizeof(char)); if (!data) return -1; strncpy(data, buffer, size+1); file_linetoOps(data, &operation, '='); //printf("op = %s data = %s\n", operation, data); // find correct operation if (!strcmp(operation, "set")) { // set if (atoi(data) != 0) { // need a new set //add_set(); set_add_after_current(); currset = pshow->sets->currset; } } else if (!strcmp(operation, "counts")) { // counts currset->counts = atoi(data); } else if (!strcmp(operation, "tempo")) { // tempo //printf("changing tempo\n"); //printf("%i: new tempo = %i\n", pstate.setnum, atoi(data)); change_tempo(atoi(data), &pshow->currtempo); update_tempo(); //printf("ping\n"); } else if (!strcmp(operation, "coords:")) { // store coords i = 0; do { free(buffer); excode = file_getValidLine(fp, &buffer); if (excode == -1) exit(-1); else if (!strcmp(buffer, "done")) break; size = strlen(buffer); free(data); data = (char*)malloc((size+2)*sizeof(char)); if (excode == -1) exit(-1); strncpy(data, buffer, size+1); for (j=0; j<size && buffer[j] != ':'; j++) data[j] = buffer[j]; data[j] = '\0'; cnum = atoi(data); j++; // pass any whitespace for (j=j; j<size && buffer[j] == ' '; j++) { } index = j; // get first number for (j=j; j<size && buffer[j] != ' '; j++) { data[j-index] = buffer[j]; } data[j-index] = '\0'; x = atof(data); // pass whitespace for (j=j; j<size && buffer[j] == ' '; j++) { } index = j; // get second number for (j=j; j<size; j++) { data[j-index] = buffer[j]; } data[j-index] = '\0'; y = atof(data); //printf("(x,y) = %i %.2f %.2f\n", cnum, x, y); //printf("valid = %i\n", perfs[i]->valid); //if (perfs[i]->valid != 0) //{ //coords_set_coord(pshow, cnum, x, y); coords_set(pshow->sets->currset->coords[cnum], x, y); //} perf_set_valid(pshow->perfs[i]); i++; } while (i < perfnum); } free(operation); free(data); } while (excode != 1); free(buffer); set_first(); update_tempo(); fclose(fp); // update valid flags //printf("perfnum = %i\n", perfnum); undo_destroy(&pstate.undobr, pshow); return 0; }