/* * dcperturb.c Jim Piper 01-03-88 * * Find the intersection of candidate crossing polygon and chromosome * medial axis. Look at profile in this neighbourhood, and if it * has a local minimum within 4 points, move the crossing by the * appropriate amount. * * MODIFICATIONS * ------------- */ #include #include #include #include dcperturb(cpol,mpol,prof) struct object *cpol,*mpol,*prof; { int i,cross,minp,crossp,*hv,xd,yd,min,minfound; struct histogramdomain *hdom; struct polygondomain *uspaxis8(), *poly, *mpoly; struct fvertex *fvtx; struct ivertex *ivtx; double xdiff,ydiff; poly = (struct polygondomain *)cpol->idom; mpoly = (struct polygondomain *)mpol->idom; fvtx = (struct fvertex *)mpoly->vtx; hdom = (struct histogramdomain *)prof->idom; cpol->idom = (struct intervaldomain *)uspaxis8(poly); cross = intsecax(cpol,mpol); /* * search back */ minp = cross; hv = hdom->hv + cross; min = *hv; /* fprintf(stderr,"dcperturb: cross %d val %d ",cross,min); */ hv--; minfound = 0; if (*hv <= min) { for (i=cross-1; i>=0 && i>cross-5; i--,hv--) { if (*hv < min) { minp = i; min = *hv; } else if (*hv > min) { minfound++; break; } } } if (!minfound) { /* * search forward */ hv = hdom->hv + cross; min = *hv; hv++; if (*hv <= min) { for (i=cross+1; inpoints && i min) { minfound++; break; } } } } free(cpol->idom); cpol->idom = (struct intervaldomain *) poly; if (minfound) { /* fprintf(stderr,"minpos %d minval %d ",minp,min); */ ivtx = poly->vtx; xdiff = 8.0 * (fvtx[minp].vtX - fvtx[cross].vtX); ydiff = 8.0 * (fvtx[minp].vtY - fvtx[cross].vtY); if (xdiff < 0) xdiff -= 0.49; else xdiff += 0.49; if (ydiff < 0) ydiff -= 0.49; else ydiff += 0.49; xd = (int) xdiff; yd = (int) ydiff; /* fprintf(stderr," xd %d yd %d",xd,yd); */ for (i=0; invertices; i++,ivtx++) { ivtx->vtX += xd; ivtx->vtY += yd; } } /* fprintf(stderr,"\n"); */ } /* * Find the location where the crossing profile crosses * the chromosome medial axis. * This routine expects the following conventions: * cpol to be integer-scaled-by-8 polygon * mpol to be real polygon */ int intsecax(cpol,mpol) struct object *cpol, *mpol; { struct ivertex *ivtx; struct fvertex *fvtx; struct polygondomain *cpdom,*mpdom; int i,j,mini,minj; float xdiff,ydiff,diff,diffmin; cpdom = (struct polygondomain *)cpol->idom; mpdom = (struct polygondomain *)mpol->idom; if (mpdom->type != 2 || cpdom->type != 1) { fprintf(stderr,"Xtra_p_feats: unexpected polygon types %d %d\n",mpdom->type,cpdom->type); return; } ivtx = cpdom->vtx; fvtx = (struct fvertex *)mpdom->vtx; diffmin = 1000000000.0; /* * This brute-force search for the minimum distance between * a point in either polygon needs to be improved - and can be !! */ for (i=0; invertices; i++) for (j=0; jnvertices; j++) { xdiff = ivtx[i].vtX - 8.0 * fvtx[j].vtX; ydiff = ivtx[i].vtY - 8.0 * fvtx[j].vtY; diff = xdiff*xdiff + ydiff*ydiff; if (diff < diffmin) { diffmin = diff; mini = i; minj = j; } } return(minj); }