int process_contour(Image *img, Rect clipr, uchar *cimg, int w, int h, int st, uchar *colors) { int i; short *pt; int npt, apt; Contour contr; apt = 32768; pt = malloc(2 * apt * sizeof pt[0]); uchar color[4]; enum { MaxError = 5 }; /* highlight cracks */ drawrect(img, clipr, color(0x00, 0xff, 0x00, 0xff)); Tess tess[16]; for(i = 0; i < nelem(tess); i++) inittess(tess+i); initcontour(&contr, cimg, w, h, st); int fid; while((npt = nextcontour(&contr, pt, apt, 0, &fid)) != -1){ short orig[2] = { -1, -1 }; int area; int poly[4096]; int npoly; if(npt == apt){ fprintf(stderr, "out of points!\n"); continue; } area = ptarea(pt, npt, orig); if(area > 0){ if((npoly = fitpoly(poly, nelem(poly), pt, npt, MaxError)) == -1) continue; /* not enough points */ if(npoly == nelem(poly) || npoly < 3) continue; if(polyarea(pt, poly, npoly, orig) < 0){ continue; } tessaddpoly(tess+fid, pt, poly, npoly); } else { ptreverse(pt, npt); npoly = fitpoly(poly, nelem(poly), pt, npt, MaxError); if(npoly == nelem(poly) || npoly < 3) continue; if(polyarea(pt, poly, npoly, orig) < 0){ continue; } polyreverse(poly, npoly); tessaddpoly(tess+fid, pt, poly, npoly); } } free(pt); int ntris; int j; for(j = 0; j < nelem(tess); j++){ if((ntris = tesstris(tess+j, &pt)) != -1){ memcpy(color, colors+4*j, sizeof color); for(i = 0; i < ntris; i++){ //idx2color(j, color); //memcpy(color, poscolor, sizeof color); pt[6*i+0+0] += clipr.u0; pt[6*i+0+1] += clipr.v0; pt[6*i+2+0] += clipr.u0; pt[6*i+2+1] += clipr.v0; pt[6*i+4+0] += clipr.u0; pt[6*i+4+1] += clipr.v0; drawtri(img, clipr, pt+6*i+0, pt+6*i+2, pt+6*i+4, color); } free(pt); } freetess(tess+j); } return 0; }
static int fitfit(struct objlist *obj,N_VALUE *inst,N_VALUE *rval,int argc,char **argv) { struct fitlocal *fitlocal; int i,through,dimension,deriv,disp; enum FIT_OBJ_TYPE type; double x,y,x0,y0,converge,wt; struct narray *darray; double *data,*wdata; char *equation,*func,prm[32]; int dnum,num,err,err2,err3; enum FitError rcode; double derror,correlation,pp; int ecode; int weight,anum; if (_exeparent(obj,(char *)argv[1],inst,rval,argc,argv)) return 1; _getobj(obj,"_local",inst,&fitlocal); if (set_equation(obj, inst, fitlocal, NULL)) return 1; equation = g_strdup("undef"); if (equation == NULL) return 1; if (set_equation(obj, inst, fitlocal, equation)) { g_free(equation); return 1; } num=0; derror=0; correlation=0; pp=0; if (_putobj(obj,"number",inst,&num)) return 1; if (_putobj(obj,"error",inst,&derror)) return 1; if (_putobj(obj,"correlation",inst,&correlation)) return 1; for (i = 0; i < 10; i++) { snprintf(prm, sizeof(prm), "%%%02d", i); if (_putobj(obj, prm, inst, &pp)) return 1; } _getobj(obj,"type",inst,&type); _getobj(obj,"through_point",inst,&through); _getobj(obj,"point_x",inst,&x0); _getobj(obj,"point_y",inst,&y0); _getobj(obj,"poly_dimension",inst,&dimension); _getobj(obj,"user_func",inst,&func); _getobj(obj,"derivative",inst,&deriv); _getobj(obj,"converge",inst,&converge); _getobj(obj, "id", inst, &(fitlocal->id)); for (i = 0; i < 10; i++) { snprintf(prm, sizeof(prm), "parameter%d", i); _getobj(obj, prm, inst, &(fitlocal->coe[i])); } _getobj(obj,"display",inst,&disp); if (through && (type == FIT_TYPE_USER)) { error(obj,ERRTHROUGH); return 1; } darray = (struct narray *) (argv[2]); if (arraynum(darray) < 1) return FitError_Small; data=arraydata(darray); anum=arraynum(darray)-1; dnum=nround(data[0]); data += 1; if (dnum == (anum / 2)) { weight = FALSE; wt = 0; /* dummy code to avoid compile warnings */ wdata = NULL; /* dummy code to avoid compile warnings */ } else if (dnum == (anum / 3)) { weight = TRUE; wdata = data + 2 * dnum; } else { error(obj, ERR_INCONSISTENT_DATA_NUM); return 1; } num=0; err2=err3=FALSE; for (i=0;i<dnum;i++) { x=data[i*2]; y=data[i*2+1]; if (weight) { wt = wdata[i]; } err=FALSE; switch (type) { case FIT_TYPE_POW: if (y<=0) err=TRUE; else y=log(y); if (x<=0) err=TRUE; else x=log(x); break; case FIT_TYPE_EXP: if (y<=0) err=TRUE; else y=log(y); break; case FIT_TYPE_LOG: if (x<=0) err=TRUE; else x=log(x); break; case FIT_TYPE_POLY: case FIT_TYPE_USER: /* nothing to do */ break; } if (err) { err2 = TRUE; } else if (weight && (wt <= 0)) { err=TRUE; err3=TRUE; } if (!err) { data[num*2]=x; data[num*2+1]=y; if (weight) { wdata[num] = wt; } num++; } } if (err2) error(obj,ERRLN); if (err3) error(obj,ERRNEGATIVEWEIGHT); if (through) { err=FALSE; switch (type) { case FIT_TYPE_POW: if (y0<=0) err=TRUE; else y0=log(y0); if (x0<=0) err=TRUE; else x0=log(x0); break; case FIT_TYPE_EXP: if (y0<=0) err=TRUE; else y0=log(y0); break; case FIT_TYPE_LOG: if (x0<=0) err=TRUE; else x0=log(x0); break; case FIT_TYPE_POLY: /* nothing to do */ break; case FIT_TYPE_USER: /* never reached */ break; } if (err) { error(obj,ERRPOINT); return 1; } } if (type != FIT_TYPE_USER) { rcode=fitpoly(fitlocal,type,dimension,through,x0,y0,data,num,disp,weight,wdata); } else { rcode=fituser(obj,fitlocal,func,deriv,converge,data,num,disp,weight,wdata); } switch (rcode) { case FitError_Fatal: return 1; break; case FitError_Small: ecode = ERRSMLDATA; break; case FitError_Matrix: ecode = ERRSINGULAR; break; case FitError_Equation: ecode = ERRNOEQS; break; case FitError_Syntax: ecode = ERRSYNTAX; break; case FitError_Range: ecode = ERRRANGE; break; /* case FitError_Convergence: ecode = ERRCONVERGE; break; */ case FitError_Interrupt: ecode = ERRINTERRUPT; break; default: ecode = 0; } if (ecode!=0) { error(obj,ecode); return 1; } if (_putobj(obj,"number",inst,&(fitlocal->num))) return 1; if (_putobj(obj,"error",inst,&(fitlocal->derror))) return 1; if (_putobj(obj,"correlation",inst,&(fitlocal->correlation))) return 1; for (i = 0; i < 10; i++) { snprintf(prm, sizeof(prm), "%%%02d", i); if (_putobj(obj, prm, inst, &(fitlocal->coe[i]))) return 1; } if (set_equation(obj, inst, fitlocal, fitlocal->equation)) return 1; fitlocal->equation = NULL; return 0; }