예제 #1
0
 public Point3D cross(Point3D p)
 {
     return new Point3D(
         Y * p.Z - Z * p.Y,
         Z * p.X - X * p.Z,
         X * p.Y - Y * p.X );
 }
예제 #2
0
        public void parallelPath(ref List<double> EastingExp, ref List<double> NorthingExp, double displacement)
        {
            ///////////////////////////////////////////////////////////////////////////////////////////////////////
            //find a parallel path to the path stored in the polygonMath object
            //strategy:
            // consider the segments before and after the current ith point
            // find two points on these two segments that are equidistance from ith point
            // Form a line between these two points
            // The midpoint of this line and the original point form a bisector of the adjacent line
            // Move along this Bisector, outward,  from the point by the desired epansion distance
            // take care with three edge vertices that are in a perfect line
            ////////////////////////////////////////////////////////////////////////////////////////////////////////

            Point3D s1 = new Point3D();
            Point3D s2 = new Point3D();
            Point3D u1 = new Point3D();
            Point3D u2 = new Point3D();
            double magP=0.0, magM=0.0;

            //take care of the interior points -- start-end points are special cases
            for (int i = 0; i < numLatLonPoints; i++)
            {

                if (i < numLatLonPoints - 1)  //exclude last point fro below test
                {
                    //note:  X to the North, Y to the east and Z is down (right hand rule)
                    double delXP = Northing[i + 1] - Northing[i];
                    double delYP = Easting[i + 1] - Easting[i];
                    magP = Math.Sqrt(delXP * delXP + delYP * delYP);
                    //vector along segment
                    s2 = new Point3D(delXP, delYP, 0.0);

                    //unit vector orthogonal to and to the left of i->i+1 segment
                    u2 = s2.unit(magP, s2.cross(new Point3D(0.0, 0.0, 1.0)));
                }
                if (i > 0)  //exclude first point from below test
                {
                    //test to see if the i-1->i point segment has zero length
                    double delXM = Northing[i] - Northing[i-1];
                    double delYM = Easting[i]  - Easting[i-1];
                    magM = Math.Sqrt(delXM * delXM + delYM * delYM);
                    //vector along segment
                    s1 = new Point3D(delXM, delYM, 0.0);

                    //unit vector orthogonal to and to the left of ith segment
                    u1 = s1.unit(magM, s1.cross(new Point3D(0.0, 0.0, 1.0)));
                }

                //handle the special cases for the first and last
                if (i == 0 )  //first point
                {
                    NorthingExp.Add(Northing[i] + displacement * u2.X);
                    EastingExp.Add(Easting[i]   + displacement * u2.Y);
                    continue;
                }
                else if ( i == (numLatLonPoints - 1))  //last point
                {
                    NorthingExp.Add(Northing[i] + displacement * u1.X);
                    EastingExp.Add(Easting[i]   + displacement * u1.Y);
                    continue;
                }

                //compute theta -- signed angle between unit vectors
                double sinTheta = u1.cross(u2).Z;   //sign indicates the direction of the turn (to right or to left)
                double cosTheta = u1.dot(u2);       //should be positve if the abs(angle change) is < 90 deg

                //gives an angle between +/- 90 deg
                double theta = Math.Atan2(sinTheta, cosTheta);

                //force the angle to be between 0-180 deg;
                //if (theta < 0) theta += Math.PI / 2.0;

                //two cases depending on the angle between the two neighbor segments
                //parallel path always placed the left of the input path
                //TODO -- need to offer an option of right or left or centered parallel paths
                if (sinTheta > 0)
                {
                    //compute point on the parallel path -- partallel path segments are parallel to input path segments
                    NorthingExp.Add(Northing[i] + displacement * ((u1.X + u2.X) / 2.0) / Math.Cos(theta / 2.0 ) );
                    EastingExp.Add(Easting[i]   + displacement * ((u1.Y + u2.Y) / 2.0) / Math.Cos(theta / 2.0 ) );
                }
                else
                {
                    //compute point on the parallel path -- partallel path segments are parallel to input path segments
                    double beta = Math.PI - theta;  //also restricted to 0-180 deg
                    NorthingExp.Add(Northing[i] + displacement * ((u1.X + u2.X) / 2.0) / Math.Cos(theta / 2.0));
                    EastingExp.Add(Easting[i]   + displacement * ((u1.Y + u2.Y) / 2.0) / Math.Cos(theta / 2.0));
                }
            }
        }
예제 #3
0
 public Point3D unit(double magnitude, Point3D p)
 {
     return new Point3D( p.X/magnitude, p.Y/magnitude, p.Z/magnitude);
 }
예제 #4
0
 public double dot(Point3D p)
 {
     return X * p.X + Y * p.Y + Z * p.Z;
 }