void fractal::draw_border( bool is_active ) { color_t color = is_active ? v->get_color(0, 255, 0) // green color : v->get_color(96, 128, 96); // green-gray color // top border drawing_area area0( off_x-1, off_y-1, size_x+2, 1, dm ); for (int i=-1; i<size_x+1; ++i) area0.put_pixel(color); // bottom border drawing_area area1( off_x-1, off_y+size_y, size_x+2, 1, dm ); for (int i=-1; i<size_x+1; ++i) area1.put_pixel(color); // left border drawing_area area2( off_x-1, off_y, 1, size_y+2, dm ); for (int i=0; i<size_y; ++i) area2.set_pixel(0, i, color); // right border drawing_area area3( size_x+off_x, off_y, 1, size_y+2, dm ); for (int i=0; i<size_y; ++i) area3.set_pixel(0, i, color); }
/*------------------------- AFFINE CONVEX EROSION -------------------------*/ static void aceros(DPoint* in, int size, std::vector<DPoint>& out, double area_sz) { // deal with singular cases (less than 2 points) if(size<2) return; // test if the curve is closed DPoint* pmax = in+size; bool is_closed = (*in==pmax[-1]); if(is_closed) --pmax; // deal with singular cases (2 or 3 points, closed) if(size<4 && is_closed) return; // return input if segment or area_sz=0 if(size==2 || area_sz==0.) { while(in!=pmax) out.push_back(*in++); return; } // compute total area double tot_area = area_pol(in, in+1, pmax-1); tot_area = ABS(tot_area); // check extinction if (is_closed) { if(area_sz>=tot_area/2.1) // theoretically: 2.0 return; } else if(area_sz>=tot_area) { out.push_back(*in); out.push_back(pmax[-1]); return; } if(!is_closed) out.push_back(*in); DPoint *p=in, *p0=p, *q0=in+1, *p1=in+1, *q1=in+2; double cur_area=0.0; bool okp=false, okq=false; do { // MAIN LOOP: compute the middle points of significative chords if(cur_area<=area_sz) { double inc_area = area3(q0, q1, p0); if(cur_area+inc_area>=area_sz) { // compute middle point double lambda = double((area_sz-cur_area)/inc_area); out.push_back(.5*(*p0+(1-lambda)**q0+lambda**q1)); } if(cur_area+inc_area-area3(p0,p1,q1)>area_sz) { cur_area -= area3(p0, p1, q0); p0 = p1++; if(is_closed && p1==pmax) p1 -= size-1; if(p0==p) okp = true; } else { cur_area += inc_area; q0 = q1++; if(is_closed && q1==pmax) q1 -= size-1; if(q0==p+1) okq = true; } } else { double inc_area = area3(p0, p1, q0); if(cur_area-inc_area<=area_sz) { // compute middle point double lambda = double((cur_area-area_sz)/inc_area); out.push_back(.5*(*q0+(1-lambda)**p0+lambda**p1)); } if(!is_closed && q1!=pmax && cur_area-inc_area+area3(p1, q0, q1)<area_sz) { cur_area += area3(p0, q0, q1); q0 = q1++; if(is_closed && q1==pmax) q1 -= size-1; if(q0==p+1) okq = true; } else { cur_area -= inc_area; p0 = p1++; if(is_closed && p1==pmax) p1 -= size-1; if(p0==p) okp = true; } } // more precise computation of cur_area if needed if(p1==q0) cur_area = 0.0; DPoint* p2 = p1+1; if(is_closed && p2==pmax) p2 -= size-1; if(p2==q0) cur_area = area3(p0, p1, q0); } while(!(is_closed? (okp&&okq): ((q0+1==pmax&&cur_area<=area_sz)))); // add last point to output out.push_back(is_closed? out.front(): pmax[-1]); }