Angle Angle::operator/(const double& rad) { Angle temp; temp.degrees = degrees / toDegs(rad); temp.radians = radians / rad; return temp; }
void Angle::setRadians(double rad) { radians = rad; degrees = toDegs(rad); }
//void animateRotationToNode(OglTree T, node n, enum FlagTypes rotateTo, float x, float y, float z) // move to node, but offset by xyz void animateRotationToObject(struct PickableObject *p) /* On menu selection of double click, animate a rotation that brings either a leaf node or a fan into the foreground at a nice position. Responding to a menu driven taxon name selection, with ROTATE_TO_NODE we move until the leaf's node position is centered on the screen and "close". Responding to a double click on a visible fan, with ROTATE_TO_TREE we move until the center of the fan is centered on the screen and close. Close is determined by 'finalEyeDistance', currently set to a fraction of the root tree's radius. */ { extern float theta[3], theta0[3]; area A, Athis,Aanc; int i; extern double gRadiusOfOriginalCircle; extern float xStep,yStep,thetaStep,zStep,theta0step; extern int animSteps; extern node gTreeRoot; OglTree t; float startTheta,endTheta,curTheta,startZ,endZ,startTheta0,endTheta0,diff0,diffTheta, radius; float x,z; OglTree T=p->tree; float y=-p->height/2.0; node n=p->nd; enum ObjectType objType=p->objType; // if the node is part of a subtree, find the marked ancestor node, and use its coordinates float finalEyeDistance; // the distance from eye to tree or node after animation is over. float deltaX=0.0, deltaY=0.0, angle; switch (objType) { case LABEL: // rotate to make a label on any kind of tree front and center t=T; if (t) while (t->layout == circle) { A = (area)(n->data); // this will recurse through the leaf's ancestors. angle = A->theta_center - t->upDirection; // what about petiole??? deltaX += -sin(angle)*(t->outerRadius+t->petioleLength); deltaY += cos(angle)*(t->outerRadius+t->petioleLength); // sin and cos are backwards from intuition; remember the fans go n = t->parentNode; //printf ("%f %f %f %f\n",toDegs(angle),deltaX, deltaY,t->upDirection); t=t->anc; } A=(area)(n->data); finalEyeDistance = t->radius/10.0; // for example radius = A->r_center + finalEyeDistance; break; case IMAGE: switch (T->layout) { case circle: return; case solid_cone: A=(area)(n->data); finalEyeDistance = T->radius/10.0; // for example //y=-0.2*T->outerRadius; // for taxon name, zoom to leaf node position radius = A->r_center + finalEyeDistance; } break; case FAN: // rotate to make fan front and center if (T->layout == fanlet) return; if (T->anc) switch (T->anc->layout) { case solid_cone: A=(area)(T->parentNode->data); finalEyeDistance = T->anc->radius/10.0; // for example radius = A->r_center + finalEyeDistance; break; case circle: break; } break; } #define ANIM_STEPS_FACTOR 3000 // bigger is smoother and slower animSteps = ANIM_STEPS_FACTOR/gTreeRoot->numdescEffective + 1; // scale the number of animation steps to be fewer in large trees... startTheta=theta[2]; diffTheta= - (90 + theta[2] + toDegs(A->theta_center) ); // took a lot of peering to get this right if ( diffTheta > 180 ) diffTheta -= 360; if ( diffTheta < -180 ) diffTheta += 360; //printf("Initial theta = %f target theta = %f adjusted diff = %f\n",startTheta,endTheta,diffTheta); thetaStep=diffTheta/animSteps; extern OglTree gCurrOglTree; zStep=(radius-gP->Z)/animSteps; yStep=(A->z-gP->Y - y + deltaY)/animSteps; xStep= (-gP->X + deltaX)/animSteps; // put the viewer back lined up with x=0 startTheta0=theta[0]; // this is putting the tree back to its completely vertical original pos endTheta0=theta0[0]; diff0 = endTheta0 - startTheta0; if ( diff0 > 180 ) diff0 -= 360; if ( diff0 < -180 ) diff0 += 360; theta0step = diff0/animSteps; glutIdleFunc(animateTwist); }