In computational ry, there are already mature algorithms for basic operations, such as shape and sum, difference, and sum ..
However, in practical application, there is also a case where less research is made:
Conditions are given: a graph is cut with a line (the beginning and end of the line are not associated). The image point is equivalent to cutting a graph. the trajectory of this line is the path of the scissors.
Result: The original area cannot be changed.
Graphical form, single ring, multi-ring, with holes in the ring.
At the beginning, I thought it was quite simple. I could solve it in a day or two. I found it was not as simple as I thought. it took nearly a week to get the code in two thousand lines .. the transcript is listed below
In addition, because the process is still a bit complicated, there is also a possibility that there will be a picture that should be split after the holes are built, not processed, and will be processed again when there is no space in the future, so let's leave your thoughts and remind me.
Interested students can contact the author in the following ways to discuss: QQ: 9492175 E-MAIL: DZQ168@21cn.com
2013.3.24
Let's take a look at the following:
Overall Thinking:
Int dzq_polygon_clip (dzq_polygon * subject_polygon, // Polygon
Dzq_vertex_list * vertex_lis, // the line to be brought in. The line is not closed.
Dzq_polygon_list * result_polygon) // linked list of the result
// Note: The linked list of the result_polygon result should be generated into an object before the call.
// This function has a very small bug, mainly because it removes tiny overlapping lines from the graph, which will reduce the area, but all of them can be controlled within the range of 1e-10.
// Another case is the hole in the result ring, so you can dig yourself into two lines without splitting. (This is a good solution, but it needs to be recursive multiple times. When the number of cropping knife marks reaches 30 or more, it consumes a lot of memory. Therefore, it does not split Multiple Graphs in this case .)
// If it is correct, 1 is returned. If it is incorrect,-1 is returned. If there is no scissors, 0 is returned.
Main steps:
Loop each outer ring.
Result generated by line removal and loop: dzq_generate_polygon function processing.
1. The ring is divided into two parts. Split the ring and save it as PPL. If no new one is generated, write it down.
2. Add the inner ring (hole) PPC together
2.1 The Outer Ring and the line generate a convex part of the BPPV.
Most data is generated and stored in dzq_polygon_clip (dzq_diff, PPL, PPC, PL1) pl1.
Generates another part of the split section dzq_polygon_clip (dzq_diff, subject_polygon, PL1, pl2); In pl2
Generate dzq_polygon_clip (dzq_int, subject_polygon, bp, pl3); // find the center of the convex intersection of holes in pl3
If no data is generated, the output is exited:
Intersection of PL1 and convex pl2. dzq_polygon_clip (dzq_int, PL1, pl3, pl4); if there is a result, it is divided into two parts for processing.
Call dzq_eliminatesmicropolygon in sequence to process the completed part of the tiny deletion.
Call dzq_splitpolygon again to recursively generate the image and use the same method as above to deal with it. dzq_splitpolygon Recursive Function Description:
Bool dzq_splitpolygon (dzq_polygon * P, dzq_polygon * PC, dzq_polygon_list * result_polygon, int irecursion)
{// Split the original image
// P is the source image, which may have holes
// PC is the hole Parameter
// Result_polygon is the result linked list.
// The number of irecursion recursion first uses dzq_splitpointinline to process its own split to check whether it is a bit online in its own ring. If yes, it is split into two lines.
Remove your own holes
Add all the holes.
// C header file bool dzq_intersect, dzq_pt * s); // determines whether the two-phase segment is intersecting, and finds out the vertex, collinearity false, non-collinearity non-intersection false, intersection or the endpoint is trueint dzq_ptinpolygon (dzq_vertex * vertex, dzq_vertex_list * vertex_lis); // determines whether the vertex is in the bool rectangle (dzq_polygon * clip_polygon); // determines whether a single graph has a self-Intersecting Line bool trim (dzq_vertex_list * vertex_lis ); // whether a single graph has a self-Intersecting Line bool dzq_polygon_intersect (dzq_polygon * clip_polygon); // whether a multi-graph has a self-Intersecting Line bool Scheme (dzq_vertex_list * polygon_lis, // line dzq_vertex_list * line_lis, // line dzq_vertex_list * result_lis, // result int iinoutin =-1); // position of the intersection point-1, online 0, out, 1. Use a line segment to cut the image. This line segment is not closed. // if it is correct, 1 is returned,-1 is returned incorrectly, and 0 int dzq_polygon_clip (dzq_polygon * subject_polygon, // returns the polygon dzq_vertex_list * vertex_lis, // The incoming line. The line can be a non-closed int * num_polygon, // The number of generated dzq_polygon_list * result_polygon); // The result linked list, bool dzq_splitpointinline (dzq_polygon * P ); // split multiple charts bool dzq_splitpolygon (dzq_polygon * P, dzq_polygon * PC, dzq_polygon_list * result_polygon, int irecursion = 0) on another line ); // split the original image bool dzq_eliminatesmicropoint (dzq_vertex_list * vertex_lis); // remove the collinearity, that is, generate a micro-line triangle image. For each line, use bool trim (dzq_polygon * P ); // remove a line in an object that does not constitute a triangle. dzq_polygon * partition (partition * V); // generate a simple single line surface double dzq_polygon_area (partition * vertex_lis) by line; // calculate a single graphic Area Double dzq_polygon_area (dzq_polygon * clip_polygon ); // calculate the shpobject * dzq_conveyshape (dzq_polygon * clip_polygon) of the graphic area; // convert the dzq from the surface to the shpobject * psobject; // convert the area shape to the dzq
Bool dzq_splitholeinline (dzq_polygon * P) {// This is where the hole may be online. // there is only one possibility that the vertex of the hole is online. then it may be connected. // There is a bug in this function. There is still no good way to deal with the case of hollows. Int C, H, V, I, j; double area_abc; double dbvalve = 1.1e-10; // This is the threshold value. If the area is smaller than this value, int iholes; // The number of holes iholes = 0; If (p-> num_contours <2) return false; // there is only one line. Nothing can be done. for (C = 0; C <p-> num_contours; C ++) {If (0! = P-> hole [c]) iholes ++;} If (iholes <1) return false; // No holes, no need to do so. How can this sentence be so meaningful, is it truth! // Extract all the holes. dzq_vertex_list * line_hole = (dzq_vertex_list *) malloc (iholes * sizeof (dzq_vertex_list); // line dzq_vertex * hole_line; iholes = 0; for (C = 0; C <p-> num_contours; C ++) {If (0! = P-> hole [c]) {line_hole [iholes]. num_vertices = p-> contour [C]. num_vertices; hole_line = (dzq_vertex *) malloc (line_hole [iholes]. num_vertices * sizeof (dzq_vertex); line_hole [iholes]. vertex = hole_line; for (I = 0; I <line_hole [iholes]. num_vertices; I ++) {hole_line [I]. X = p-> contour [C]. vertex [I]. x; hole_line [I]. y = p-> contour [C]. vertex [I]. Y ;}iholes ++; // number of holes }/// process each line and each hole to see if any vertex exists on the outer ring dzq_pt PLT, PLS, ple; // three dots in T num_vertices; // Number of vertices of the line for (C = 0; C <p-> num_contours; C ++) {If (0! = P-> hole [c]) continue; // It is a hole and is not processed. num_vertices = p-> contour [C]. num_vertices; // Number of vertices of the line for (H = 0; H <iholes; H ++) // each hole ring {// make sure all holes are in the ring bool bpinline = false; for (I = 0; I <line_hole [H]. num_vertices; I ++) // each vertex of the hole {If (0 = dzq_ptinpolygon (line_hole [H]. vertex + I, p-> contour + C) {// bpinline = true; break ;}} if (true = bpinline) continue outside the outer ring; // has this hole changed the outer ring? Bool bholeringchange = false; // has this ring been changed once by this hole? // All the holes are online. You can continue. For (I = 0; I <line_hole [H]. num_vertices; I ++) // each vertex of the hole {PLT. X = line_hole [H]. vertex [I]. x; // The xplt of the first vertex. y = line_hole [H]. vertex [I]. y; // yfor (V = 0; v <num_vertices; V ++) of the First vertex // each line segment of each outer ring {PLS. X = p-> contour [C]. vertex [v]. x; PLS. y = p-> contour [C]. vertex [v]. y; ple. X = p-> contour [C]. vertex [(V + 1) % num_vertices]. x; ple. y = p-> contour [C]. vertex [(V + 1) % num_vertices]. y; area_abc = (PLS. x-ple. x) * (PLT. y-ple. y)-(PLS. Y-ple. y) * (PLT. x-ple. x); area_abc = FABS (area_abc); If (area_abc <= dbvalve // The area of the triangle is twice smaller than one value & (eqd (PLT. x, min (PLS. x, ple. x) & eqx (PLT. x, max (PLS. x, ple. x) // X also contains & (eqd (PLT. y, min (PLS. y, ple. y) & eqx (PLT. y, max (PLS. y, ple. y) // y {// The vertex is on this line. // generate a new line to determine // dzq_vertex_list * line_1 = (dzq_vertex_list *) malloc (1 * sizeof (dzq_vertex_list) on the outer ring of Beibei line 1 )); // line dzq_vertex_list * line_2 = (d Optional *) malloc (1 * sizeof (dzq_vertex_list); // The line dzq_vertex * line1_vertex, * line2_vertex; line_1-> num_vertices = num_vertices; line1_vertex = (dzq_vertex *) malloc (line_1-> num_vertices * sizeof (dzq_vertex); line_1-> vertex = line1_vertex; int ilinenew_num = 0; // current offset of the vertex of the new line for (j = V + 1; j <num_vertices + V + 1; j ++) // because it is an outer ring, is {line‑vertex [ilinenew_num] Starting from the last point. X = p-> contour [C]. vertex [J % num_vertices]. x; Lin E1_vertex [ilinenew_num]. y = p-> contour [C]. vertex [J % num_vertices]. y; ilinenew_num ++;} // copy the int h_num_vertices = line_hole [h] of the 2-hole outlet. num_vertices; // Number of vertex numbers in the hole line_2-> num_vertices = h_num_vertices; line2_vertex = (dzq_vertex *) malloc (line_2-> num_vertices * sizeof (dzq_vertex )); line_2-> vertex = line2_vertex; ilinenew_num = 0; For (j = I; j