/** * @brief Get the next point in the object path based on movement converting the positions from * polar coordinates to vector for the calculation and back again to be returned. * @param[in] movement The distance that the object needs to move. * @param[in] originalPoint The point from which the object is moving. * @param[in] orthogonalVector The orthogonal vector. * @param[out] finalPoint The next point from the original point + movement in "angle" direction. */ static void AIRFIGHT_GetNextPointInPathFromVector (const float *movement, const vec2_t originalPoint, const vec3_t orthogonalVector, vec2_t finalPoint) { vec3_t startPoint, finalVectorPoint; PolarToVec(originalPoint, startPoint); RotatePointAroundVector(finalVectorPoint, orthogonalVector, startPoint, *movement); VecToPolar(finalVectorPoint, finalPoint); }
/** * @brief Return longitude and latitude of a point of the screen for 3D geoscape (globe) * @param[in] node The current menuNode we have clicked on (3dmap or map) * @param[in] x,y Coordinates on the screen that were clicked on * @param[out] pos vec2_t was filled with longitude and latitude * @sa MAP_3DMapToScreen */ void uiGeoscapeNode::screenTo3DMap (const uiNode_t* node, int x, int y, vec2_t pos) { vec2_t mid; vec3_t v, v1, rotationAxis; float dist; const float radius = GLOBE_RADIUS; /* set mid to the coordinates of the center of the globe */ Vector2Set(mid, UI_MAPEXTRADATACONST(node).mapPos[0] + UI_MAPEXTRADATACONST(node).mapSize[0] / 2.0f, UI_MAPEXTRADATACONST(node).mapPos[1] + UI_MAPEXTRADATACONST(node).mapSize[1] / 2.0f); /* stop if we click outside the globe (distance is the distance of the point to the center of the globe) */ dist = sqrt((x - mid[0]) * (x - mid[0]) + (y - mid[1]) * (y - mid[1])); if (dist > radius) { Vector2Set(pos, -1.0, -1.0); return; } /* calculate the coordinates in the local frame * this frame is the frame of the screen. * v[0] is the vertical axis of the screen * v[1] is the horizontal axis of the screen * v[2] is the axis perpendicular to the screen - we get its value knowing that norm of v is egal to radius * (because the point is on the globe) */ v[0] = - (y - mid[1]); v[1] = - (x - mid[0]); v[2] = - sqrt(radius * radius - (x - mid[0]) * (x - mid[0]) - (y - mid[1]) * (y - mid[1])); VectorNormalize(v); /* rotate the vector to switch of reference frame * note the ccs.angles[ROLL] is always 0, so there is only 2 rotations and not 3 * and that GLOBE_ROTATE is already included in ccs.angles[YAW] * first rotation is along the horizontal axis of the screen, to put north-south axis of the earth * perpendicular to the screen */ VectorSet(rotationAxis, 0, 1, 0); RotatePointAroundVector(v1, rotationAxis, v, UI_MAPEXTRADATACONST(node).angles[YAW]); /* second rotation is to rotate the earth around its north-south axis * so that Greenwich meridian is along the vertical axis of the screen */ VectorSet(rotationAxis, 0, 0, 1); RotatePointAroundVector(v, rotationAxis, v1, UI_MAPEXTRADATACONST(node).angles[PITCH]); /* we therefore got in v the coordinates of the point in the static frame of the earth * that we can convert in polar coordinates to get its latitude and longitude */ VecToPolar(v, pos); }