Пример #1
0
        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=====================================================================
        }
Пример #2
0
        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);
        }