/*! * \ingroup HGU_GL * \brief Trackball animation time-out procedure which calls any * trackball callbacks and then if the trackball is in * it's animation mode reregisters itself as a time-out * procedure. * \param clientData Used to pass the trackball instance. * \param id Timeout function id. */ static void HGUglwCanvasTbAnimateFn(XtPointer clientData, XtIntervalId *id) { Widget givenW; HGUglwCanvasTbWidget tbW; HGUglwCanvasTbPart *ctb; HGUglwCanvasCallbackStruct cb; givenW = (Widget )clientData; tbW = (HGUglwCanvasTbWidget )clientData; ctb = &(tbW->hguGLwCanvasTb); WLZ_VTX_3_ADD(ctb->translateCurrent, ctb->translateCurrent, ctb->translateDelta); ctb->rotateCurrent = HGUglQuatProduct(ctb->rotateCurrent, ctb->rotateDelta); cb.reason = HGUglw_CR_TRACKBALL; cb.event = &(ctb->tbEvent); cb.width = tbW->core.width; cb.height = tbW->core.height; cb.glxCtx = tbW->hguGLwCanvas.glxCtx; XtCallCallbacks((Widget )tbW, HGUglwNtrackballCallback, &cb); if(ctb->trackballMode != HGUglwCANVASTB_MODE_ANIMATION) { ctb->animateFnId = 0; } else { ctb->animateFnId = XtAppAddTimeOut(XtWidgetToApplicationContext(givenW), ctb->animateInterval, HGUglwCanvasTbAnimateFn, clientData); } }
/*! * \return Coordinates of centre of mass. * \ingroup WlzFeatures * \brief Computes the centre of mass of a vector of 3D vertices. * \param nVtx Number of vertices. * \param vtx The vertices. */ WlzDVertex3 WlzCentreOfMassVtx3D(int nVtx, WlzDVertex3 *vtx) { WlzDVertex3 cen; WLZ_VTX_3_ZERO(cen); if(nVtx > 0) { int idx; for(idx = 0; idx < nVtx; ++idx) { WLZ_VTX_3_ADD(cen, cen, vtx[idx]); } WLZ_VTX_3_SCALE(cen, cen, 1.0 / nVtx); } return(cen); }
/*! * \return Woolz error code. * \ingroup WlzTransform * \brief Walks along a line segment calling the given function. * \param obj Object passed to function. * \param fn Function to call. * \param pWSp Workspace in which the start and end positions, * a valid interval domain and sufficent * intervals have been set. */ static WlzErrorNum WlzProfileWalk( WlzObject *obj, WlzProfileWalkFn fn, WlzProfileWalkWSp *pWSp) { int i, m; WlzIVertex3 d, e, p, s; WlzErrorNum errNum = WLZ_ERR_NONE; WLZ_VTX_3_SUB(d, pWSp->end, pWSp->start); WLZ_VTX_3_SIGN(s, d); WLZ_VTX_3_ABS(d, d); m = ALG_MAX3(d.vtX, d.vtY, d.vtZ); WLZ_VTX_3_SET(e, m / 2, m / 2, m / 2); i = m; pWSp->index = 0; pWSp->inside = 0; p = pWSp->start; while(1) { WlzIVertex3 t0, t1; errNum = (*fn)(obj, p, pWSp); if((errNum != WLZ_ERR_NONE) || (--i < 0)) { break; } ++(pWSp->index); WLZ_VTX_3_SUB(e, e, d); WLZ_VTX_3_SET(t0, (e.vtX < 0), (e.vtY < 0), (e.vtZ < 0)); WLZ_VTX_3_SCALE_ADD(e, t0, m, e); WLZ_VTX_3_HAD(t1, t0, s); WLZ_VTX_3_ADD(p, p, t1); } return(errNum); }
/*! input is the voxsel sip and the unit vector nStraghtline, indicating direction in OPT space. output is the *sip1p in view space! */ static WlzErrorNum WlzGetCorssPoint( WlzVertex sip, WlzVertex nStraghtline, WlzVertex *sip1p, WlzThreeDViewStruct *wlzViewStri ) { WlzVertex vtemp, vtemp0, vo, vso, vtx1; WlzVertex vs1, nI; double dtemp, dtemp1, dtemp2; WlzErrorNum errNum = WLZ_ERR_NONE; /* output for test */ /* printf("Yaw: %f\n", wlzViewStri->theta*180.0/3.14); printf("Pitch: %f\n", wlzViewStri->phi*180.0/3.14 ); printf("Roll: %f\n", wlzViewStri->zeta*180.0/3.14 ); printf("distance: %f\n", wlzViewStri->dist ); printf("scaling: %f\n", wlzViewStri->scale ); printf("%f %f %f\n", wlzViewStri->fixed.vtX, wlzViewStri->fixed.vtY ,wlzViewStri->fixed.vtZ ); */ vtx1.d3.vtX = 0.0; vtx1.d3.vtY = 0.0; vtx1.d3.vtZ = 1.0; /* get the normal n_i = nI.d3 of this plan i -plane do not need !!! */ errNum = Wlz3DSectionTransformInvVtxR(wlzViewStri, vtx1.d3, &nI.d3 ); /* in OPT space */ /* check the n_{i} * nStraghtline != 0 other wise throw an erro */ dtemp = WLZ_VTX_3_DOT(nStraghtline.d3, nI.d3); /* dtemp = abs(dtemp); */ if( ( dtemp < 0.000001 ) && ( dtemp > -0.000001 ) ) { printf("%lg\n",dtemp); printf(" the n_{i} is verticl to n_straght line in OPT space,\n"); printf(" there is no crossed point. Please chose different straight\n"); printf("line and try again\n "); printf("%lg %lg %lg\n", nI.d3.vtX, nI.d3.vtY, nI.d3.vtZ); printf("%lg %lg %lg\n", nStraghtline.d3.vtX, nStraghtline.d3.vtY, nStraghtline.d3.vtZ); exit( 1 ); } else { /* not parallel to z-direction */ /* s_{i} = x_{i} + n_straight_line * s = x_{i} + n_straight_line * < [ O_{i} - x_{i} ] dot n_{i} / ( n_straightline dot n_{i} ) > */ /* dtemp = ( n_straightlien dot n_{i} ) aleady got */ /* get the o_i+1 vo.d3.vtX = wlzViewStr1->fixed.vtX + wlzViewStr->dist * nI.d3.vtX; vo.d3.vtY = wlzViewStr1->fixed.vtY + wlzViewStr->dist * nI.d3.vtY; vo.d3.vtY = wlzViewStr1->fixed.vtZ + wlzViewStr->dist * nI.d3.vtZ; */ WLZ_VTX_3_SCALE(vtemp0.d3, nI.d3, wlzViewStri->dist); WLZ_VTX_3_ADD(vo.d3, wlzViewStri->fixed, vtemp0.d3); /* vso.d3 = vo.d3 - vx.d3 */ WLZ_VTX_3_SUB(vso.d3,vo.d3,sip.d3); /* vs0.d3 dot n_i */ dtemp1 = WLZ_VTX_3_DOT(vso.d3, nI.d3); /* get the s */ dtemp2 = dtemp1 / dtemp; /* vtemp.d3 = ( n_straightlien * s ) */ WLZ_VTX_3_SCALE(vtemp.d3, nStraghtline.d3, dtemp2 ); /* now get the p_{i} */ WLZ_VTX_3_ADD(vs1.d3, sip.d3, vtemp.d3 ); } /*---- get the p_{i}' = T_{i} p_{i} ----*/ errNum = Wlz3DSectionTransformVtxR(wlzViewStri, vs1.d3, &vtemp.d3 ); sip1p->d3.vtX = vtemp.d3.vtX; sip1p->d3.vtY = vtemp.d3.vtY; sip1p->d3.vtZ = vtemp.d3.vtZ; printf("%lg %lg %lg\n", sip1p->d3.vtX, sip1p->d3.vtY, sip1p->d3.vtZ ); return errNum; }
/*! * - Function: WlzTrack3DVertical * - Returns: WlzVetex * - Purpose: Track vertex through neighbour layer. * - Parameters: * * -# sip: input WlzVertex. * -# sip1p: output WlzVertex by tracking. * -# wlzViewStri: WlzThreeDViewStruct for layer i; * -# wlzViewStrip1: WlzThreeDViewStruct for the next layer i+-1; * -# UpOrDown: > 0 Up; <= 0 down; * - Author: J. Rao, R. Baldock */ static WlzErrorNum WlzTrack3DVertical( WlzVertex sip, WlzVertex *sip1p, WlzThreeDViewStruct *wlzViewStri, WlzThreeDViewStruct *wlzViewStrip1, int UpOrDown) { WlzVertex vtemp, vtemp0, vs, vo, vso, vtx1; WlzVertex vs1, nI, nIP1; double dtemp, dtemp1, dtemp2; WlzErrorNum errNum = WLZ_ERR_NONE; /* output for test */ /* printf("Yaw: %f\n", wlzViewStri->theta*180.0/3.14); printf("Pitch: %f\n", wlzViewStri->phi*180.0/3.14 ); printf("Roll: %f\n", wlzViewStri->zeta*180.0/3.14 ); printf("distance: %f\n", wlzViewStri->dist ); printf("scaling: %f\n", wlzViewStri->scale ); printf("%f %f %f\n", wlzViewStri->fixed.vtX, wlzViewStri->fixed.vtY ,wlzViewStri->fixed.vtZ ); */ /* vtemp0.d3 = (sx', sy', sz') */ WlzValueCopyDVertexToDVertex3(&vtemp0.d3, &sip.d3, 1); vtemp0.d3.vtZ = wlzViewStri->dist; /* reverse affine transformation the vertx to get vs.d3 = s_i here is in OPT space */ errNum = Wlz3DSectionTransformInvVtxR(wlzViewStri, vtemp0.d3, &vs.d3 ); printf("%f %f %f\n", vs.d3.vtX, vs.d3.vtY, vs.d3.vtZ); /* as the vs.d3 is in OPT space and we want vertical tracking we have: vs1.d3.vtX = vs.d3.vtX vs1.d3.vtY = vs.d3.vtY vs1.d3.vtZ = ? need to be find !!!!! vs1.d3.vtZ = vs.d3.vtZ + s where s n_z dot n_{i+1} = [ O_{i+1} - r_{i} ] dot n_{i+1} */ /* nz.d3.vtX = 0.0; nz.d3.vtY = 0.0; nz.d3.vtZ = 1.0; if( UpOrDown <= 0 ) { nz.d3.vtZ = -1.0; } */ vtx1.d3.vtX = 0.0; vtx1.d3.vtY = 0.0; vtx1.d3.vtZ = 1.0; /* get the normal n_i = nI.d3 of this plan i -plane do not need !!! */ errNum = Wlz3DSectionTransformInvVtxR(wlzViewStri, vtx1.d3, &nI.d3 ); /* get the normal n_i(+-1) = nIP1.d3 of the next plan i+-1 -plane */ errNum = Wlz3DSectionTransformInvVtxR(wlzViewStrip1, vtx1.d3, &nIP1.d3 ); /* track the s_{i+-1} vertically in OPT space */ /* check the n_{i+1}_z != 0 other wise throw an erro */ dtemp = nIP1.d3.vtZ; /* dtemp = abs(dtemp); */ if( ( dtemp < 0.00000001 ) && ( dtemp > -0.00000001 ) ) { printf("%lg\n",dtemp); printf(" the z-component of n_{i+1} is zero in OPT space, we can't track vertically\n "); printf("%lg %lg %lg\n", nIP1.d3.vtX, nIP1.d3.vtY, nIP1.d3.vtZ); exit( 1 ); } else { /* not parallel to z-direction */ /* s_{i+1} = S_{i} + n_z * s = S_{i} + n_z * < [ O_{i+1} - r_{i} ] dot n_{i+1} / ( n_z dot n_{i+1} ) > */ /* dtemp = ( n_z dot n_{i+1} ) */ dtemp = WLZ_VTX_3_DOT(vtx1.d3, nIP1.d3); /* get the o_i+1 vo.d3.vtX = wlzViewStr1->fixed.vtX + wlzViewStr->dist * nIP1.d3.vtX; vo.d3.vtY = wlzViewStr1->fixed.vtY + wlzViewStr->dist * nIP1.d3.vtY; vo.d3.vtY = wlzViewStr1->fixed.vtZ + wlzViewStr->dist * nIP1.d3.vtZ; */ WLZ_VTX_3_SCALE(vtemp0.d3, nIP1.d3, wlzViewStrip1->dist); WLZ_VTX_3_ADD(vo.d3, wlzViewStrip1->fixed, vtemp0.d3); /* vso.d3 = vo.d3 - vs.d3 */ WLZ_VTX_3_SUB(vso.d3,vo.d3,vs.d3); /* vs0.d3 dot n_i+1 */ dtemp1 = WLZ_VTX_3_DOT(vso.d3, nIP1.d3); /* get the s */ dtemp2 = dtemp1 / dtemp; /* vtemp.d3 = ( n_z * s ) */ WLZ_VTX_3_SCALE(vtemp.d3, vtx1.d3, dtemp2 ); /* now get the s_{i+1} */ WLZ_VTX_3_ADD(vs1.d3, vs.d3, vtemp.d3 ); } /*---- get the s_{i+1}' = T_{i+1} s_{i+1} ----*/ errNum = Wlz3DSectionTransformVtxR(wlzViewStrip1, vs1.d3, &vtemp.d3 ); sip1p->d3.vtX = vtemp.d3.vtX; sip1p->d3.vtY = vtemp.d3.vtY; sip1p->d3.vtZ = vtemp.d3.vtZ; printf("%lg %lg %lg\n", sip1p->d3.vtX, sip1p->d3.vtY, sip1p->d3.vtZ ); return errNum; }