public static bool IsInsideOfPlane(Point3D inPoint, Point3D inP1, Point3D inP2, Point3D inP3, double dblProximityValue) { double l, m, n, k; Vector3D normal = Vector3D.CrossProduct(CommonFunctions.GetVector(inP2) - CommonFunctions.GetVector(inP1), (CommonFunctions.GetVector(inP3) - CommonFunctions.GetVector(inP1))); l = normal.X; m = normal.Y; n = normal.Z; k = -(inP1.X * l + inP1.Y * m + inP1.Z * n); /* Modified on 29-Jan-04. Even if the point is outside but close enough to the plane, * //we will consider it to be inside of it.================================================= * if(valFromPlaneEqn(inPoint, l, m, n, k) <= 0 ) * return true ; * else * return false ; */ if (PlaneEquation.ValueInPlaneEquation(inPoint, l, m, n, k) <= dblProximityValue) { return(true); } else { return(false); } //End of modification===================================================================== }
public static bool SetNearFarRectangle(ref Point3D[] arrFarPlane, ref Point3D[] arrNearPlane, ref double dNear, ref double dFar, ref bool blnCamInCuboid, Point3D[] arrCuboidFt, Point3D[] arrCuboidBk, Point3D inCameraLocation, Point3D inLookingAt, CameraRatio cameraRatio, bool blnCameraAtInfinity, double dblProximityValue) { //////////////////Variable Declaration//////////////////////////////////////////////////// //constants for the plane equation double l; double m; double n; double k; //constant for the plane passing through inCameraLocation double kFarPlane; //constant in the far plane equation double kNearPlane; //constant in the near plane equation double sign; double tempVal; bool flgFound; //flag to indicate whether the target cuboid is within the aperture of the //image taken double maxConst = 0.0f; //Stores the maximum value that should be added to the equation of plane //passing through inCameraLocation, so that a far plane is decided //which covers up all the cuboid points to be processed uint i; //Counter variable Vector3D vDirection = new Vector3D(); Vector3D upDirection = new Vector3D(); Vector3D rightDirection = new Vector3D(); //directions on the far plane double dtr, t; //used in calculating distance of midPt from the camera location Point3D midPt = new Point3D(); Point3D midPtNear = new Point3D(); //the point at the center of the far rectangle double xScope, yScope; //half lengths of the area covered by the camera on Far rectangle double distance; //distance of midPt from the camera location ///////////////////////////////////////////////////////////////////////////////////////// /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~step 1~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ /* Find the equation of the plane passing through the inCameraLocation. Equation is in */ /* the form x l + y m + z n + k = 0 */ //get the direction of view vDirection = new Vector3D(inLookingAt.X, inLookingAt.Y, inLookingAt.Z) - new Vector3D(inCameraLocation.X, inCameraLocation.Y, inCameraLocation.Z); if (vDirection.Length == 0) { throw new Exception("The looking vector was found to be null"); } //divide by modulus to get the unit vector vDirection = vDirection / vDirection.Length; //directional cosines of the plane l = vDirection.X; m = vDirection.Y; n = vDirection.Z; //constant for the equation of plane k = -(inCameraLocation.X * l + inCameraLocation.Y * m + inCameraLocation.Z * n); /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~step 2~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ /* Get the equation of the far plane parallel to this plane and enclosing all the */ /* Cuboid points and the CameraLocation on the same side */ //target cuboid points which are in range should lie on the same side of the plane passing //through CameraLocation sign = PlaneEquation.ValueInPlaneEquation(inLookingAt, l, m, n, k); //If any of the target cuboid points gives the same sign, then the cuboid has to be //processed, otherwise it lies outside the purview of the taken snapshot flgFound = false; for (i = 0; i <= 7; i++) { if (i <= 3) { tempVal = PlaneEquation.ValueInPlaneEquation(arrCuboidFt[i], l, m, n, k); } else { tempVal = PlaneEquation.ValueInPlaneEquation(arrCuboidBk[i - 4], l, m, n, k); } //i-4 is done to traverse from 0 to 3 for back face after traversing through //the front face if (CommonFunctions.HasSameSigns(sign, tempVal)) { if (flgFound == false) { maxConst = tempVal; flgFound = true; } else if (CommonFunctions.ModValue(maxConst) < CommonFunctions.ModValue(tempVal)) { maxConst = tempVal; } } } if (flgFound) { kFarPlane = k - maxConst; // constant for the equation of the far plane } else { throw new Exception("Image shot out of target"); } /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ step 3 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ /* Make the bounding rectangle on the far plane. We need to find out the four */ /* directions from the central point on the plane along which the four corner points */ /* lie. If the view direction would have been along the -ve z axis, then the upward */ /* direction would have been the positive direction of y axis and moving towards */ /* right would mean moving in the positive direction of x axis. */ //check whether the vector is along the x, y or z axis if (vDirection.X != 0 && vDirection.Y == 0 && vDirection.Z == 0) { //aligned along the x axis upDirection = new Vector3D(0.0f, 1.0f, 0.0f); if (vDirection.X > 0) { rightDirection = new Vector3D(0.0f, 0.0f, 1.0f); } else { rightDirection = new Vector3D(0.0f, 0.0f, -1.0f); } } else if (vDirection.Y != 0 && vDirection.X == 0 && vDirection.Z == 0) { //aligned along the y axis if (vDirection.Y > 0) { upDirection = new Vector3D(0.0f, 0.0f, 1.0f); } else { upDirection = new Vector3D(0.0f, 0.0f, -1.0f); } rightDirection = new Vector3D(1.0f, 0.0f, 0.0f); } else if (vDirection.Z != 0 && vDirection.Y == 0 && vDirection.X == 0) { //aligned along the z axis upDirection = new Vector3D(0.0f, 1.0f, 0.0f); if (vDirection.Z > 0) { rightDirection = new Vector3D(-1.0f, 0.0f, 0.0f); } else { rightDirection = new Vector3D(1.0f, 0.0f, 0.0f); } } else if (vDirection.X == 0 && vDirection.Y != 0 && vDirection.Z != 0) { //In the yz plane if (vDirection.Z < 0) { rightDirection = new Vector3D(1.0f, 0.0f, 0.0f); } else { rightDirection = new Vector3D(-1.0f, 0.0f, 0.0f); } upDirection = Vector3D.CrossProduct(rightDirection, vDirection); } else if (vDirection.X != 0 && vDirection.Y == 0 && vDirection.Z != 0) { //In the xz plane upDirection = new Vector3D(0.0f, 1.0f, 0.0f); rightDirection = Vector3D.CrossProduct(vDirection, upDirection); } else if (vDirection.X != 0 && vDirection.Y != 0 && vDirection.Z == 0) { //In the xy plane if (vDirection.X > 0) { rightDirection = new Vector3D(0.0f, 0.0f, 1.0f); } else { rightDirection = new Vector3D(0.0f, 0.0f, -1.0f); } upDirection = Vector3D.CrossProduct(rightDirection, vDirection); } else if (vDirection.X != 0 && vDirection.Y != 0 && vDirection.Z != 0) { //Not along the axis, neither along the three planes if ((vDirection.Z < 0 && vDirection.X > 0) || (vDirection.Z > 0 && vDirection.X < 0)) { upDirection = Vector3D.CrossProduct(new Vector3D(vDirection.X, 0.0f, 0.0f), vDirection); } else { upDirection = Vector3D.CrossProduct(vDirection, new Vector3D(vDirection.X, 0.0f, 0.0f)); } rightDirection = Vector3D.CrossProduct(vDirection, upDirection); } /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Step 4~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ /* Find the co-ordinates of the point at which the perpendicular line from the */ /* CameraLocation intersects the far plane. Since the point lies on the line it should */ /* satisfy the following equations : x = x1 + l t; y = y1 + m t; z = z1 + n t; */ /* Putting the values for the point in the equation of the plane: xl+ym+zn+kFarPlane=0 */ /* we can get the value of t. */ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ dtr = l * l + m * m + n * n; if (dtr == 0) { throw new Exception("Division by zero attempted in set near far rectangle function"); } t = -(kFarPlane + inCameraLocation.X * l + inCameraLocation.Y * m + inCameraLocation.Z * n) / dtr; midPt = new Point3D(inCameraLocation.X + l * t, inCameraLocation.Y + m * t, inCameraLocation.Z + n * t); /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Step 5~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ /*~Adjust the magnitude of the vectors so that they cover the required area in ~*/ /*~the far plane ~*/ if (blnCameraAtInfinity) { if (cameraRatio.xRangeAtInfinity <= 0 || cameraRatio.yRangeAtInfinity <= 0) { throw new Exception("Invalid range at infinity values found in the set near far rectangle function."); } //Correction done on 28th Jan 2004. The infinite range values should also be //divided by two //xScope = dataPtr.cameraRatio.xRangeAtInfinity; //yScope = dataPtr.cameraRatio.yRangeAtInfinity; xScope = cameraRatio.xRangeAtInfinity / 2.0f; yScope = cameraRatio.yRangeAtInfinity / 2.0f; } else { distance = (CommonFunctions.GetVector(midPt) - CommonFunctions.GetVector(inCameraLocation)).Length; xScope = (distance * cameraRatio.xRatio) / 2.0f; yScope = (distance * cameraRatio.yRatio) / 2.0f; } if (upDirection.Length != 0 && rightDirection.Length != 0) { upDirection = upDirection * (yScope / upDirection.Length); rightDirection = rightDirection * (xScope / rightDirection.Length); } else { throw new Exception("Division by zero attempted in set near far rectangle function."); } /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Step 6~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ /* Using the vector equations and this point, find the corners of the far plane */ //top left arrFarPlane[0].X = midPt.X + upDirection.X - rightDirection.X; arrFarPlane[0].Y = midPt.Y + upDirection.Y - rightDirection.Y; arrFarPlane[0].Z = midPt.Z + upDirection.Z - rightDirection.Z; //bottom left arrFarPlane[1].X = midPt.X - upDirection.X - rightDirection.X; arrFarPlane[1].Y = midPt.Y - upDirection.Y - rightDirection.Y; arrFarPlane[1].Z = midPt.Z - upDirection.Z - rightDirection.Z; //bottom right arrFarPlane[2].X = midPt.X - upDirection.X + rightDirection.X; arrFarPlane[2].Y = midPt.Y - upDirection.Y + rightDirection.Y; arrFarPlane[2].Z = midPt.Z - upDirection.Z + rightDirection.Z; //top right arrFarPlane[3].X = midPt.X + upDirection.X + rightDirection.X; arrFarPlane[3].Y = midPt.Y + upDirection.Y + rightDirection.Y; arrFarPlane[3].Z = midPt.Z + upDirection.Z + rightDirection.Z; /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Step 7~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ /* Find distance of the Near Plane from Camera if it lies outside the cuboid. ~~~~~~~~*/ if (WithinFrustum(inCameraLocation, arrCuboidFt, arrCuboidBk, dblProximityValue)) { blnCamInCuboid = true; } else { blnCamInCuboid = false; //find the distance of the near plane from the camera location for (i = 0; i <= 7; i++) { if (i <= 3) { tempVal = PlaneEquation.ValueInPlaneEquation(arrCuboidFt[i], l, m, n, kFarPlane); } else { tempVal = PlaneEquation.ValueInPlaneEquation(arrCuboidBk[i - 4], l, m, n, kFarPlane); } if (i == 0) { maxConst = tempVal; } else if (CommonFunctions.ModValue(maxConst) < CommonFunctions.ModValue(tempVal)) { maxConst = tempVal; } } kNearPlane = kFarPlane - maxConst; //constant for the near plane dNear = CommonFunctions.ModValue(k - kNearPlane); //distances of near and far plane dFar = CommonFunctions.ModValue(k - kFarPlane); //from the CameraLocation } /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Step 8~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ /*~~~~~ If the object is at infinity then define the corners of the near plane ~~~~~~~*/ if (blnCameraAtInfinity) { //mblnCamAtInfinity = true ; if (blnCamInCuboid) { throw new Exception("Error occured inside the set near far rectangle function: Camera at infinity found inside the cuboid."); } //get the middle point of the near plane midPtNear = CommonFunctions.GetMiddlePoint(inCameraLocation, midPt, dNear, dFar); /* Using the vector equations and this point, find the corners of the near plane */ //top left arrNearPlane[0].X = midPtNear.X + upDirection.X - rightDirection.X; arrNearPlane[0].Y = midPtNear.Y + upDirection.Y - rightDirection.Y; arrNearPlane[0].Z = midPtNear.Z + upDirection.Z - rightDirection.Z; //bottom left arrNearPlane[1].X = midPtNear.X - upDirection.X - rightDirection.X; arrNearPlane[1].Y = midPtNear.Y - upDirection.Y - rightDirection.Y; arrNearPlane[1].Z = midPtNear.Z - upDirection.Z - rightDirection.Z; //bottom right arrNearPlane[2].X = midPtNear.X - upDirection.X + rightDirection.X; arrNearPlane[2].Y = midPtNear.Y - upDirection.Y + rightDirection.Y; arrNearPlane[2].Z = midPtNear.Z - upDirection.Z + rightDirection.Z; //top right arrNearPlane[3].X = midPtNear.X + upDirection.X + rightDirection.X; arrNearPlane[3].Y = midPtNear.Y + upDirection.Y + rightDirection.Y; arrNearPlane[3].Z = midPtNear.Z + upDirection.Z + rightDirection.Z; } //else //mblnCamAtInfinity = false ; return(true); }