/*! * \return Coordinates of centre of mass. * \ingroup WlzFeatures * \brief Computes the centre of mass of a vector of 2D vertices. * \param nVtx Number of vertices. * \param vtx The vertices. */ WlzDVertex2 WlzCentreOfMassVtx2D(int nVtx, WlzDVertex2 *vtx) { WlzDVertex2 cen; WLZ_VTX_2_ZERO(cen); if(nVtx > 0) { int idx; for(idx = 0; idx < nVtx; ++idx) { WLZ_VTX_2_ADD(cen, cen, vtx[idx]); } WLZ_VTX_2_SCALE(cen, cen, 1.0 / nVtx); } return(cen); }
/*! * \return void * \brief Outputs the mesh and displaced mesh of the given mesh * transform as Postscript to the standard error output. * \param mObj Given mesh transform object. * \param sObj Source object. * \param dilObj Dilated object. * \param outObj Transformed object. */ static void WlzCMeshOutputPS(WlzObject *mObj, WlzObject *sObj, WlzObject *dilObj, WlzObject *outObj) { int idE, idN, useElm; double scale; double *dsp; WlzDVertex2 pos, offset; WlzDVertex2 elmVx[3]; WlzDBox2 bBox; WlzCMeshNod2D *nod; WlzCMeshElm2D *elm; WlzCMesh2D *mesh; WlzIndexedValues *ixv; WlzObject *bObj = NULL; char buf[100]; (void )fprintf(stderr, "%%!\n" "/Times-Courier findfont\n" "1 scalefont\n" "setfont\n" "1 setlinecap\n" "1 setlinejoin\n" "0.01 setlinewidth\n"); if((mObj != NULL) && (mObj->type == WLZ_CMESH_2D) && ((mesh = mObj->domain.cm2) != NULL) && ((ixv = mObj->values.x) != NULL)) { /* Compute the bounding box of the mesh transform. */ bBox.xMin = bBox.yMin = DBL_MAX; bBox.xMax = bBox.yMax = DBL_MIN; for(idN = 0; idN < mesh->res.nod.maxEnt; ++idN) { nod = (WlzCMeshNod2D *)AlcVectorItemGet(mesh->res.nod.vec, idN); if(nod->idx >= 0) { if(nod->pos.vtX < bBox.xMin) { bBox.xMin = nod->pos.vtX; } else if(nod->pos.vtX > bBox.xMax) { bBox.xMax = nod->pos.vtX; } if(nod->pos.vtY < bBox.yMin) { bBox.yMin = nod->pos.vtY; } else if(nod->pos.vtY > bBox.yMax) { bBox.yMax = nod->pos.vtY; } dsp = (double *)WlzIndexedValueGet(ixv, idN); pos.vtX = nod->pos.vtX + dsp[0]; pos.vtY = nod->pos.vtY + dsp[1]; if(pos.vtX < bBox.xMin) { bBox.xMin = pos.vtX; } else if(pos.vtX > bBox.xMax) { bBox.xMax = pos.vtX; } if(pos.vtY < bBox.yMin) { bBox.yMin = pos.vtY; } else if(pos.vtY > bBox.yMax) { bBox.yMax = pos.vtY; } } } if(((pos.vtX = fabs(bBox.xMax - bBox.xMin)) > 1.0) && ((pos.vtY = fabs(bBox.yMax - bBox.yMin)) > 1.0)) { /* Compute scale and offset for an A4 page. */ if((4.0 * pos.vtX) > (3.0 * pos.vtY)) { scale = 500.0 / (bBox.xMax - bBox.xMin); } else { scale = 700.0 / (bBox.yMax - bBox.yMin); } offset.vtX = (bBox.xMin * scale) - 50; offset.vtY = (bBox.yMin * -scale) - 750; (void )fprintf(stderr, "255 0 0 setrgbcolor\n"); for(idE = 0; idE < mesh->res.elm.maxEnt; ++idE) { elm = (WlzCMeshElm2D *)AlcVectorItemGet(mesh->res.elm.vec, idE); if(elm->idx >= 0) { for(idN = 0; idN < 3; ++idN) { pos = elm->edu[idN].nod->pos; elmVx[idN].vtX = (pos.vtX * scale) - offset.vtX; elmVx[idN].vtY = (pos.vtY * -scale) - offset.vtY; } (void )fprintf(stderr, "%g %g moveto " "%g %g lineto " "%g %g lineto " "%g %g lineto " "stroke\n", elmVx[0].vtX, elmVx[0].vtY, elmVx[1].vtX, elmVx[1].vtY, elmVx[2].vtX, elmVx[2].vtY, elmVx[0].vtX, elmVx[0].vtY); WLZ_VTX_2_ADD3(pos, elmVx[0], elmVx[1], elmVx[2]); WLZ_VTX_2_SCALE(pos, pos, 0.333333); (void )sprintf(buf, "%d", elm->idx); (void )fprintf(stderr, "%g %g moveto " "(%s) show\n", pos.vtX, pos.vtY, buf); } } (void )fprintf(stderr, "0 0 255 setrgbcolor\n"); for(idE = 0; idE < mesh->res.elm.maxEnt; ++idE) { elm = (WlzCMeshElm2D *)AlcVectorItemGet(mesh->res.elm.vec, idE); if(elm->idx >= 0) { /* Display only those elements that have all nodes inside the * domain. useElm = ((elm->edg[0].nod->flags | elm->edg[1].nod->flags | elm->edg[2].nod->flags) & WLZ_CMESH_NOD_FLAG_OUTSIDE) == 0; */ useElm = 1; if(useElm) { for(idN = 0; idN < 3; ++idN) { pos = elm->edu[idN].nod->pos; dsp = (double *)WlzIndexedValueGet(ixv, elm->edu[idN].nod->idx); pos.vtX += dsp[0]; pos.vtY += dsp[1]; elmVx[idN].vtX = (pos.vtX * scale) - offset.vtX; elmVx[idN].vtY = (pos.vtY * -scale) - offset.vtY; } (void )fprintf(stderr, "%g %g moveto " "%g %g lineto " "%g %g lineto " "%g %g lineto " "stroke\n", elmVx[0].vtX, elmVx[0].vtY, elmVx[1].vtX, elmVx[1].vtY, elmVx[2].vtX, elmVx[2].vtY, elmVx[0].vtX, elmVx[0].vtY); WLZ_VTX_2_ADD3(pos, elmVx[0], elmVx[1], elmVx[2]); WLZ_VTX_2_SCALE(pos, pos, 0.333333); (void )sprintf(buf, "%d", elm->idx); (void )fprintf(stderr, "%g %g moveto " "(%s) show\n", pos.vtX, pos.vtY, buf); } } } (void )fprintf(stderr, "0 255 0 setrgbcolor\n"); if((bObj = WlzObjToBoundary(sObj, 1, NULL)) != NULL) { WlzBndOutputPS(bObj->domain.b, scale, offset); } (void )fprintf(stderr, "0 255 255 setrgbcolor\n"); if((bObj = WlzObjToBoundary(dilObj, 1, NULL)) != NULL) { WlzBndOutputPS(bObj->domain.b, scale, offset); } (void )fprintf(stderr, "127 0 127 setrgbcolor\n"); if((bObj = WlzObjToBoundary(outObj, 1, NULL)) != NULL) { WlzBndOutputPS(bObj->domain.b, scale, offset); } (void )fprintf(stderr, "showpage\n"); } } }