/*****************************************************************************/ /* */ /* F I S T : Fast, Industrial-Strength Triangulation */ /* */ /*****************************************************************************/ /* */ /* (C) Martin Held */ /* (C) Universitaet Salzburg, Salzburg, Austria */ /* */ /* This code is not in the public domain. All rights reserved! Please make */ /* sure to read the full copyright statement contained in api_functions.cpp. */ /* */ /*****************************************************************************/ /* */ /* This code is based on fragments by T. Auer. */ /* */ /*****************************************************************************/ /* */ /* get standard libraries */ /* */ #include #include #include /* */ /* get my header files */ /* */ #include "fpkernel.h" #include "martin.h" #include "ipe_io.h" #include "defs.h" FILE *InitIpe(ipe_iodef *ipeio, const char *file_name, machine_double xl, machine_double xr, machine_double yl, machine_double yr) { FILE *ipe_file; if ((ipe_file = fopen(file_name, "w")) != NULL) { if(ipeio->ipe7) { fprintf(ipe_file, "\n\n\n\n\n\n0 0 m\n-1 0.333 l\n-1 -0.333 l\nh\n\n\n\n\n0 0 m\n-1 0.333 l\n-1 -0.333 l\nh\n\n\n\n\n0 0 m\n-1 0.333 l\n-0.8 0 l\n-1 -0.333 l\nh\n\n\n\n\n0 0 m\n-1 0.333 l\n-0.8 0 l\n-1 -0.333 l\nh\n\n\n\n\n0.6 0 0 0.6 0 0 e\n0.4 0 0 0.4 0 0 e\n\n\n\n\n0.6 0 0 0.6 0 0 e\n\n\n\n\n\n0.5 0 0 0.5 0 0 e\n\n\n0.6 0 0 0.6 0 0 e\n0.4 0 0 0.4 0 0 e\n\n\n\n\n\n-0.6 -0.6 m\n0.6 -0.6 l\n0.6 0.6 l\n-0.6 0.6 l\nh\n-0.4 -0.4 m\n0.4 -0.4 l\n0.4 0.4 l\n-0.4 0.4 l\nh\n\n\n\n\n-0.6 -0.6 m\n0.6 -0.6 l\n0.6 0.6 l\n-0.6 0.6 l\nh\n\n\n\n\n\n-0.5 -0.5 m\n0.5 -0.5 l\n0.5 0.5 l\n-0.5 0.5 l\nh\n\n\n-0.6 -0.6 m\n0.6 -0.6 l\n0.6 0.6 l\n-0.6 0.6 l\nh\n-0.4 -0.4 m\n0.4 -0.4 l\n0.4 0.4 l\n-0.4 0.4 l\nh\n\n\n\n\n\n\n-0.43 -0.57 m\n0.57 0.43 l\n0.43 0.57 l\n-0.57 -0.43 l\nh\n\n\n-0.43 0.57 m\n0.57 -0.43 l\n0.43 -0.57 l\n-0.57 0.43 l\nh\n\n\n\n\n\n0 0 m\n-1 0.333 l\n-1 -0.333 l\nh\n\n\n\n\n0 0 m\n-1 0.333 l\n-0.8 0 l\n-1 -0.333 l\nh\n\n\n\n\n0 0 m\n-1 0.333 l\n-0.8 0 l\n-1 -0.333 l\nh\n\n\n\n\n-1 0.333 m\n0 0 l\n-1 -0.333 l\n\n\n\n\n0 0 m\n-1 0.333 l\n-1 -0.333 l\nh\n-1 0 m\n-2 0.333 l\n-2 -0.333 l\nh\n\n\n\n\n0 0 m\n-1 0.333 l\n-1 -0.333 l\nh\n-1 0 m\n-2 0.333 l\n-2 -0.333 l\nh\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); fprintf(ipe_file, "\n\n\n"); } else { fprintf(ipe_file,"%%!PS-Adobe-2.0 EPSF-1.2\n"); fprintf(ipe_file,"%%%%Creator: Ipe 5.0\n\n"); fprintf(ipe_file,"%% Group\n\n"); } } else { throw IPE_FILE_INIT_FAILED; } SetIpeDimensions(ipeio, 0.0, 452.0, 0.0, 568.0); SetWorldDimensions(ipeio, xl, xr, yl, yr); SetScaleFactor(ipeio); return(ipe_file); } void CloseIpeFile_fist(FILE *ipe_file) { fprintf(ipe_file,"%% End\n\n"); fprintf(ipe_file,"end %%%% of Ipe figure\n"); fclose(ipe_file); return; } void CloseIpe7File(FILE *ipe_file) { fprintf(ipe_file,"\n\n"); fclose(ipe_file); return; } void WriteIpe7Line(FILE *ipe_file,double x1, double y1, double x2, double y2) { fprintf(ipe_file,"\n\ %f %f m\n\ %f %f l\n\ \n",x1,y1,x2,y2); return; } void WriteBeginGroup(FILE *ipe_file) { fprintf(ipe_file,"%% Group\n\n"); return; } void WriteEndGroup_fist(FILE *ipe_file) { fprintf(ipe_file,"%% End\n\n"); return; } void WriteEnd(FILE *ipe_file) { fprintf(ipe_file,"%% End\n\n"); return; } void WriteLineBegin(FILE *ipe_file, int dashed, machine_double width, int no_vertices) /* */ /* dashed = 0 ... solid */ /* dashed = 3855 ... strichliert */ /* dashed = 4369 ... punktiert */ /* dashed = 4095 ... lang strichliert */ /* */ { fprintf(ipe_file,"%% Line\n"); fprintf(ipe_file,"%% ss %d\n", dashed); if (width == 0.0) width = 0.4; fprintf(ipe_file,"%f [] ss\n", MDOUBLE_TO_IOMDOUBLE(width)); fprintf(ipe_file,"np %% # %d\n", no_vertices); return; } void WriteSegmentBegin(FILE *ipe_file, int dashed, machine_double width, int no_vertices) { fprintf(ipe_file,"%% Segments\n"); fprintf(ipe_file,"%% ss %d\n", dashed); if (width == 0.0) width = 0.4; fprintf(ipe_file,"%f [] ss\n", MDOUBLE_TO_IOMDOUBLE(width)); fprintf(ipe_file,"%% # %d\n", no_vertices); return; } void WriteArcBegin(FILE *ipe_file, int dashed, machine_double width) { fprintf(ipe_file,"%% Arc\n"); fprintf(ipe_file,"%% ss %d\n", dashed); if (width == 0.0) width = 0.4; fprintf(ipe_file,"%f [] ss\n", MDOUBLE_TO_IOMDOUBLE(width)); return; } void WriteObjFill(FILE *ipe_file, machine_double r, machine_double g, machine_double b) { fprintf(ipe_file,"%% fic\n"); fprintf(ipe_file,"%f %f %f sc sfi\n", MDOUBLE_TO_IOMDOUBLE(r), MDOUBLE_TO_IOMDOUBLE(g), MDOUBLE_TO_IOMDOUBLE(b)); return; } void WriteObjStroke(FILE *ipe_file, machine_double r, machine_double g, machine_double b) { if ((r == 0.0) && (g == 0.0) && (b == 0.0)) { fprintf(ipe_file,"%% sk\n"); fprintf(ipe_file,"0 sg sk\n"); fprintf(ipe_file,"%% End\n\n"); } else { fprintf(ipe_file,"%% skc\n"); fprintf(ipe_file,"%f %f %f sc sk\n", MDOUBLE_TO_IOMDOUBLE(r), MDOUBLE_TO_IOMDOUBLE(g), MDOUBLE_TO_IOMDOUBLE(b)); fprintf(ipe_file,"%% End\n\n"); } return; } void WriteArcCCW(ipe_iodef *ipeio, FILE *ipe_file, machine_double xc, machine_double yc, machine_double r, machine_double alpha, machine_double beta) /* */ /* draws a CCW arc with center (xc,yc), start-angle alpha and end-angle */ /* beta and radius r. */ /* */ { fprintf(ipe_file,"%% xy\n"); WritePnt(ipeio, ipe_file, xc, yc); fprintf(ipe_file," %% r\n"); fprintf(ipe_file,"%f %% ang\n", MDOUBLE_TO_IOMDOUBLE(r * ipeio->scale)); fprintf(ipe_file,"%f %f np arc\n", MDOUBLE_TO_IOMDOUBLE(alpha), MDOUBLE_TO_IOMDOUBLE(beta)); return; } void WriteArcCW(ipe_iodef *ipeio, FILE *ipe_file, machine_double xc, machine_double yc, machine_double r, machine_double alpha, machine_double beta) /* */ /* draws a CW arc with center (xc,yc), start-angle alpha and end-angle */ /* beta and radius r. */ /* */ { fprintf(ipe_file,"%% xy\n"); WritePnt(ipeio, ipe_file, xc, yc); fprintf(ipe_file," %% r\n"); fprintf(ipe_file,"%f %% ang\n", MDOUBLE_TO_IOMDOUBLE(r * ipeio->scale)); fprintf(ipe_file,"%f %f np arc\n", MDOUBLE_TO_IOMDOUBLE(beta), MDOUBLE_TO_IOMDOUBLE(alpha)); return; } void WriteMark(ipe_iodef *ipeio, FILE *ipe_file, machine_double r, machine_double g, machine_double b, int type, machine_double size, machine_double x, machine_double y) /* */ /* type = 1 ... circle */ /* type = 2 ... disk */ /* type = 3 ... box */ /* type = 4 ... square */ /* type = 5 ... cross */ /* */ /* standard size = 2.0 */ /* */ { if (ipeio->ipe7) { fprintf(ipe_file,"\n",(int)size); } else { fprintf(ipe_file,"%% Mark\n"); if ((r == 0.0) && (g == 0.0) && (b == 0.0)) { fprintf(ipe_file,"%% sk\n"); fprintf(ipe_file,"0 sg\n"); fprintf(ipe_file,"%% ty %d\n", type); fprintf(ipe_file,"%% sz\n"); fprintf(ipe_file,"%f\n", size); fprintf(ipe_file,"%% xy\n"); } else { fprintf(ipe_file,"%% skc\n"); fprintf(ipe_file,"%f %f %f sc\n", r, g, b); fprintf(ipe_file,"%% ty %d\n", type); fprintf(ipe_file,"%% sz\n"); fprintf(ipe_file,"%f\n", size); fprintf(ipe_file,"%% xy\n"); } WritePnt(ipeio, ipe_file, x, y); fprintf(ipe_file," m2\n"); fprintf(ipe_file,"%% End\n\n"); } return; } void WriteLineFirstPnt(ipe_iodef *ipeio, FILE *ipe_file, machine_double x, machine_double y) { WritePnt(ipeio, ipe_file, x, y); if(ipeio->ipe7) fprintf(ipe_file," m\n"); else fprintf(ipe_file," mt\n"); return; } void WriteLineNextPnt(ipe_iodef *ipeio, FILE *ipe_file, machine_double x, machine_double y) { WritePnt(ipeio, ipe_file, x, y); if(ipeio->ipe7) fprintf(ipe_file," l\n"); else fprintf(ipe_file," lt\n"); return; } void WriteSegmentFirstPnt(ipe_iodef *ipeio, FILE *ipe_file, machine_double x, machine_double y) { WritePnt(ipeio, ipe_file, x, y); if(ipeio->ipe7) fprintf(ipe_file," m\n"); else fprintf(ipe_file," N\n"); return; } void WriteSegmentNextPnt(ipe_iodef *ipeio, FILE *ipe_file, machine_double x, machine_double y) { WritePnt(ipeio, ipe_file, x, y); if(ipeio->ipe7) fprintf(ipe_file," l\n"); else fprintf(ipe_file," L\n"); return; } void WriteSegmentEndPnt(ipe_iodef *ipeio, FILE *ipe_file, machine_double x, machine_double y) { WritePnt(ipeio, ipe_file, x, y); fprintf(ipe_file," E\n"); return; } void WriteSegmentClosePnt(ipe_iodef *ipeio, FILE *ipe_file, machine_double x, machine_double y) { WritePnt(ipeio, ipe_file, x, y); fprintf(ipe_file," C\n"); return; } void WriteSplineBegin(FILE *ipe_file, int dashed, machine_double width, int no_vertices) { fprintf(ipe_file,"%% Spline\n"); fprintf(ipe_file,"%% ss %d\n", dashed); if (width == 0.0) width = 0.4; fprintf(ipe_file,"%f [] ss\n", width); fprintf(ipe_file,"np %% # %d\n", no_vertices); return; } void WriteSplineFirstPnt(ipe_iodef *ipeio, FILE *ipe_file, machine_double x, machine_double y) { WritePnt(ipeio, ipe_file, x, y); fprintf(ipe_file,"\n"); WritePnt(ipeio, ipe_file, x, y); fprintf(ipe_file,"\n"); WritePnt(ipeio, ipe_file, x, y); fprintf(ipe_file,"\n"); return; } void WriteSplineLastPnt(ipe_iodef *ipeio, FILE *ipe_file, machine_double x, machine_double y) { WritePnt(ipeio, ipe_file, x, y); fprintf(ipe_file," spl\n"); WritePnt(ipeio, ipe_file, x, y); fprintf(ipe_file," spl\n"); WritePnt(ipeio, ipe_file, x, y); fprintf(ipe_file," spl\n"); fprintf(ipe_file,"xspl\n"); return; } void WriteSplineSecondPnt(ipe_iodef *ipeio, FILE *ipe_file, machine_double x, machine_double y) { WritePnt(ipeio, ipe_file, x, y); fprintf(ipe_file," fspl\n"); return; } void WriteSplineNextPnt(ipe_iodef *ipeio, FILE *ipe_file, machine_double x, machine_double y) { WritePnt(ipeio, ipe_file, x, y); fprintf(ipe_file," spl\n"); return; } void SetIpeDimensions(ipe_iodef *ipeio, machine_double xmin, machine_double xmax, machine_double ymin, machine_double ymax) { ipeio->ipe_x_min = xmin; ipeio->ipe_x_max = xmax; ipeio->ipe_y_min = ymin; ipeio->ipe_y_max = ymax; return; } void SetWorldDimensions(ipe_iodef *ipeio, machine_double xmin, machine_double xmax, machine_double ymin, machine_double ymax) { ipeio->x_min = xmin; ipeio->x_max = xmax; ipeio->y_min = ymin; ipeio->y_max = ymax; return; } void SetScaleFactor(ipe_iodef *ipeio) { ipeio->scale = Min((ipeio->ipe_x_max - ipeio->ipe_x_min) / (ipeio->x_max - ipeio->x_min), (ipeio->ipe_y_max - ipeio->ipe_y_min) / (ipeio->y_max - ipeio->y_min)); return; } void WritePnt(ipe_iodef *ipeio, FILE *ipe_file, machine_double x, machine_double y) { machine_double xi, yi; xi = ipeio->ipe_x_min + (x - ipeio->x_min) * ipeio->scale; yi = ipeio->ipe_y_min + (y - ipeio->y_min) * ipeio->scale; fprintf(ipe_file,"%f %f", xi, yi); return; } void InitIpeDimensions(ipe_iodef *ipeio, machine_double xmin, machine_double ymin, machine_double xmax, machine_double ymax, machine_double ixmin, machine_double iymin, machine_double ixmax, machine_double iymax) { ipeio->ipe_x_min = ixmin; ipeio->ipe_x_max = ixmax; ipeio->ipe_y_min = iymin; ipeio->ipe_y_max = iymax; ipeio->x_min = xmin; ipeio->x_max = xmax; ipeio->y_min = ymin; ipeio->y_max = ymax; ipeio->scale = Min((ipeio->ipe_x_max - ipeio->ipe_x_min) / (ipeio->x_max - ipeio->x_min), (ipeio->ipe_y_max - ipeio->ipe_y_min) / (ipeio->y_max - ipeio->y_min)); return; } void WriteLineSegment(ipe_iodef *ipeio, FILE *ipe_file, machine_double r, machine_double g, machine_double b, machine_double width, int dashed, machine_double x1, machine_double y1, machine_double x2, machine_double y2) { WriteSegmentBegin(ipe_file, dashed, width, 2); WriteSegmentFirstPnt(ipeio, ipe_file, x1, y1); WriteSegmentEndPnt(ipeio, ipe_file, x2, y2); WriteObjStroke(ipe_file, r, g, b); return; } void WriteCircularArc(ipe_iodef *ipeio, FILE *ipe_file, machine_double r, machine_double g, machine_double b, machine_double width, int dashed, machine_double xc, machine_double yc, machine_double x1, machine_double y1, machine_double x2, machine_double y2, boolean ccw) { machine_double rad, alpha, beta, xvec, yvec; machine_double pi = 3.141592653589793; xvec = xc - x1; yvec = yc - y1; rad = sqrt(xvec * xvec + yvec * yvec); alpha = atan2(y1 - yc, x1 - xc); beta = atan2(y2 - yc, x2 - xc); alpha = alpha * 180.0 / pi; beta = beta * 180.0 / pi; WriteArcBegin(ipe_file, dashed, width); if (ccw) WriteArcCCW(ipeio, ipe_file, xc, yc, rad, alpha, beta); else WriteArcCW(ipeio, ipe_file, xc, yc, rad, alpha, beta); WriteObjStroke(ipe_file, r, g, b); return; } void WriteDiscretizedCircularArc(ipe_iodef *ipeio, FILE *ipe_file, machine_double xc, machine_double yc, machine_double x1, machine_double y1, machine_double x2, machine_double y2, boolean ccw, machine_double delta, int *num_segs) /* */ /* This function replaces a circular arc by a series of line segments. The */ /* discretization depends on the angular increment delta (in radians). */ /* */ /* Note that neither start-point nor end-point are drawn! */ /* */ { machine_double rad, alpha, beta, gamma, xvec, yvec; /* machine_double pi = 3.1415926535897; */ machine_double pi2 = 6.2831853071796; xvec = xc - x1; yvec = yc - y1; rad = sqrt(xvec * xvec + yvec * yvec); alpha = atan2(y1 - yc, x1 - xc); beta = atan2(y2 - yc, x2 - xc); delta /= sqrt(rad); *num_segs = 0; if (ccw) { if (beta < alpha) beta += pi2; for (gamma = alpha + delta; gamma < beta; gamma += delta) { WriteSegmentNextPnt(ipeio, ipe_file, xc + rad * cos(gamma), yc + rad * sin(gamma)); ++(*num_segs); } } else { if (alpha < beta) alpha += pi2; for (gamma = alpha - delta; gamma > beta; gamma -= delta) { WriteSegmentNextPnt(ipeio, ipe_file, xc + rad * cos(gamma), yc + rad * sin(gamma)); ++(*num_segs); } } return; }