📄 polyaprx.cpp
字号:
if (edgept->flags[FLAGS] & FIXED && edgept->flags[RUNLENGTH] == 1 /*and neighours free */ && edgept->next->flags[FLAGS] & FIXED && (edgept->prev->flags[FLAGS] & FIXED) == 0 /*same pair of dirs */ && (edgept->next->next->flags[FLAGS] & FIXED) == 0 && edgept->prev->flags[DIR] == edgept->next->flags[DIR] && edgept->prev->prev->flags[DIR] == edgept->next->next->flags[DIR] && ((edgept->prev->flags[DIR] - edgept->flags[DIR] + 1) & 7) < 3) { /*unfix it */ edgept->flags[FLAGS] &= ~FIXED; edgept->next->flags[FLAGS] &= ~FIXED; } edgept = edgept->next; /*do all points */ } while (edgept != start); /*until finished */ stopped = 0; if (area < 450) area = 450; gapmin = area * fixed_dist * fixed_dist / 44000; edgept = start; fixed_count = 0; do { if (edgept->flags[FLAGS] & FIXED) fixed_count++; edgept = edgept->next; } while (edgept != start); while ((edgept->flags[FLAGS] & FIXED) == 0) edgept = edgept->next; edgefix0 = edgept; edgept = edgept->next; while ((edgept->flags[FLAGS] & FIXED) == 0) edgept = edgept->next; edgefix1 = edgept; edgept = edgept->next; while ((edgept->flags[FLAGS] & FIXED) == 0) edgept = edgept->next; edgefix2 = edgept; edgept = edgept->next; while ((edgept->flags[FLAGS] & FIXED) == 0) edgept = edgept->next; edgefix3 = edgept; startfix = edgefix2; do { if (fixed_count <= 3) break; //already too few point_diff (d12vec, edgefix1->pos, edgefix2->pos); d12 = LENGTH (d12vec); if (d12 <= gapmin) { point_diff (d01vec, edgefix0->pos, edgefix1->pos); d01 = LENGTH (d01vec); point_diff (d23vec, edgefix2->pos, edgefix3->pos); d23 = LENGTH (d23vec); if (d01 > d23) { edgefix2->flags[FLAGS] &= ~FIXED; fixed_count--; /* if ( plots[EDGE] & PATHS ) mark(edgefd,edgefix2->pos.x,edgefix2->pos.y,PLUS); */ } else { edgefix1->flags[FLAGS] &= ~FIXED; fixed_count--; /* if ( plots[EDGE] & PATHS ) mark(edgefd,edgefix1->pos.x,edgefix1->pos.y,PLUS); */ edgefix1 = edgefix2; } } else { edgefix0 = edgefix1; edgefix1 = edgefix2; } edgefix2 = edgefix3; edgept = edgept->next; while ((edgept->flags[FLAGS] & FIXED) == 0) { if (edgept == startfix) stopped = 1; edgept = edgept->next; } edgefix3 = edgept; edgefix = edgefix2; } while ((edgefix != startfix) && (!stopped));}//#pragma OPT_LEVEL 2 /*stop compiler bugs*//********************************************************************** *poly2(startpt,area,path) applies a second approximation to the outline *using the points which have been fixed by the first approximation* **********************************************************************/EDGEPT *poly2( //second poly EDGEPT *startpt, /*start of loop */ int area /*area of blob box */ ) { register EDGEPT *edgept; /*current outline point */ EDGEPT *loopstart; /*starting point */ register EDGEPT *linestart; /*start of line */ register int edgesum; /*correction count */ if (area < 1200) area = 1200; /*minimum value */ /*1200(4) */ par1 = 4500 / (approx_dist * approx_dist); /*1200(6) */ par2 = 6750 / (approx_dist * approx_dist); loopstart = NULL; /*not found it yet */ edgept = startpt; /*start of loop */ do { /*current point fixed */ if (edgept->flags[FLAGS] & FIXED /*and next not */ && (edgept->next->flags[FLAGS] & FIXED) == 0) { loopstart = edgept; /*start of repoly */ break; } edgept = edgept->next; /*next point */ } while (edgept != startpt); /*until found or finished */ if (loopstart == NULL && (startpt->flags[FLAGS] & FIXED) == 0) { /*fixed start of loop */ startpt->flags[FLAGS] |= FIXED; loopstart = startpt; /*or start of loop */ } if (loopstart) { do { edgept = loopstart; /*first to do */ do { linestart = edgept; edgesum = 0; /*sum of lengths */ do { /*sum lengths */ edgesum += edgept->flags[RUNLENGTH]; edgept = edgept->next; /*move on */ } while ((edgept->flags[FLAGS] & FIXED) == 0 && edgept != loopstart && edgesum < 126); if (poly_debug) tprintf ("Poly2:starting at (%d,%d)+%d=(%d,%d),%d to (%d,%d)\n", linestart->pos.x, linestart->pos.y, linestart->flags[DIR], linestart->vec.x, linestart->vec.y, edgesum, edgept->pos.x, edgept->pos.y); /*reapproximate */ cutline(linestart, edgept, area); while ((edgept->next->flags[FLAGS] & FIXED) && edgept != loopstart) edgept = edgept->next; /*look for next non-fixed */ } /*do all the loop */ while (edgept != loopstart); edgesum = 0; do { if (edgept->flags[FLAGS] & FIXED) edgesum++; edgept = edgept->next; } //count fixed pts while (edgept != loopstart); if (edgesum < 3) area /= 2; //must have 3 pts } while (edgesum < 3); do { linestart = edgept; do { edgept = edgept->next; } while ((edgept->flags[FLAGS] & FIXED) == 0); linestart->next = edgept; edgept->prev = linestart; linestart->vec.x = edgept->pos.x - linestart->pos.x; linestart->vec.y = edgept->pos.y - linestart->pos.y; } while (edgept != loopstart); } else edgept = startpt; /*start of loop */ loopstart = edgept; /*new start */ return loopstart; /*correct exit */}/********************************************************************** *cutline(first,last,area) straightens out a line by partitioning *and joining the ends by a straight line* **********************************************************************/void cutline( //recursive refine EDGEPT *first, /*ends of line */ EDGEPT *last, int area /*area of object */ ) { register EDGEPT *edge; /*current edge */ TPOINT vecsum; /*vector sum */ int vlen; /*approx length of vecsum */ TPOINT vec; /*accumulated vector */ EDGEPT *maxpoint; /*worst point */ int maxperp; /*max deviation */ register int perp; /*perp distance */ int ptcount; /*no of points */ int squaresum; /*sum of perps */ edge = first; /*start of line */ if (edge->next == last) return; /*simple line */ /*vector sum */ vecsum.x = last->pos.x - edge->pos.x; vecsum.y = last->pos.y - edge->pos.y; if (vecsum.x == 0 && vecsum.y == 0) { /*special case */ vecsum.x = -edge->prev->vec.x; vecsum.y = -edge->prev->vec.y; } /*absolute value */ vlen = vecsum.x > 0 ? vecsum.x : -vecsum.x; if (vecsum.y > vlen) vlen = vecsum.y; /*maximum */ else if (-vecsum.y > vlen) vlen = -vecsum.y; /*absolute value */ vec.x = edge->vec.x; /*accumulated vector */ vec.y = edge->vec.y; maxperp = 0; /*none yet */ squaresum = ptcount = 0; edge = edge->next; /*move to actual point */ maxpoint = edge; /*in case there isn't one */ do { perp = CROSS (vec, vecsum); /*get perp distance */ if (perp != 0) { perp *= perp; /*squared deviation */ } squaresum += perp; /*sum squares */ ptcount++; /*count points */ if (poly_debug) tprintf ("Cutline:Final perp=%d\n", perp); if (perp > maxperp) { maxperp = perp; maxpoint = edge; /*find greatest deviation */ } vec.x += edge->vec.x; /*accumulate vectors */ vec.y += edge->vec.y; edge = edge->next; } while (edge != last); /*test all line */ perp = LENGTH (vecsum); ASSERT_HOST (perp != 0); if (maxperp < 256 * MAX_INT16) { maxperp <<= 8; maxperp /= perp; /*true max perp */ } else { maxperp /= perp; maxperp <<= 8; /*avoid overflow */ } if (squaresum < 256 * MAX_INT16) /*mean squared perp */ perp = (squaresum << 8) / (perp * ptcount); else /*avoid overflow */ perp = (squaresum / perp << 8) / ptcount; if (poly_debug) tprintf ("Cutline:A=%d, max=%.2f(%.2f%%), msd=%.2f(%.2f%%)\n", area, maxperp / 256.0, maxperp * 200.0 / area, perp / 256.0, perp * 300.0 / area); if (maxperp * par1 >= 10 * area || perp * par2 >= 10 * area || vlen >= 126) { maxpoint->flags[FLAGS] |= FIXED; /*partitions */ cutline(first, maxpoint, area); cutline(maxpoint, last, area); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -