コード例 #1
0
        /// <summary>
        /// Generates an approximation of a circular arc.
        /// </summary>
        /// <param name="tol">The maximum chord-to-circumference distance.</param>
        /// <returns></returns>
        public static IPointGeometry[] GetApproximation(ICircularArcGeometry g, ILength tol)
        {
            // Get info about the circle the curve lies on.
            IPosition center = g.Circle.Center;
            double    radius = g.Circle.Radius;

            // Determine the change in bearing which will satisfy the specified tolerance
            // (if no tolerance has been specified, arbitrarily use a tolerance of 1mm on the ground).
            double tolm  = (tol.Meters > Double.Epsilon ? tol.Meters : 0.001);
            double dbear = Math.Acos((radius - tolm) / radius);

            IPointGeometry start = g.BC;
            IPointGeometry end   = g.EC;
            bool           iscw  = g.IsClockwise;

            // Get the total angle subtended by the curve.
            Turn   reft   = new Turn(center, start);
            double totang = reft.GetAngleInRadians(end); // clockwise

            if (!iscw)
            {
                totang = MathConstants.PIMUL2 - totang;
            }

            // Figure out how many positions we'll generate
            int nv = (int)(totang / dbear); // truncate

            Debug.Assert(nv >= 0);

            // Handle special case of very short arc.
            if (nv == 0)
            {
                return new IPointGeometry[] { start, end }
            }
            ;

            // Sign the delta-bearing the right way.
            if (!iscw)
            {
                dbear = -dbear;
            }

            // Get the initial bearing to the first position along the curve.
            double curbear = reft.BearingInRadians + dbear;

            // Append positions along the length of the curve.
            List <IPointGeometry> result = new List <IPointGeometry>(nv);

            result.Add(start);

            for (int i = 0; i < nv; i++, curbear += dbear)
            {
                IPosition p = BasicGeom.Polar(center, curbear, radius);
                result.Add(PositionGeometry.Create(p));
            }

            result.Add(end);
            return(result.ToArray());
        }
コード例 #2
0
        /// <summary>
        /// Gets the position that is a specific distance from the start of a circular arc.
        /// </summary>
        /// <param name="g">The geometry for the circular arc</param>
        /// <param name="distance">The distance from the start of the arc.</param>
        /// <param name="result">The position found</param>
        /// <returns>True if the distance is somewhere ON the arc. False if the distance
        /// was less than zero, or more than the arc length (in that case, the position
        /// found corresponds to the corresponding terminal point).</returns>
        public static bool GetPosition(ICircularArcGeometry g, ILength distance, out IPosition result)
        {
            // Allow 1 micron tolerance
            const double TOL = 0.000001;

            // Check for invalid distances.
            double d = distance.Meters;

            if (d < 0.0)
            {
                result = g.BC;
                return(false);
            }

            double clen = g.Length.Meters; // Arc length

            if (d > (clen + TOL))
            {
                result = g.EC;
                return(false);
            }

            // Check for limiting values (if you don't do this, minute
            // roundoff at the BC & EC can lead to spurious locations).
            // (although it's possible to use TINY here, use 1 micron
            // instead, since we can't represent position any better
            // than that).

            if (d < TOL)
            {
                result = g.BC;
                return(true);
            }

            if (Math.Abs(d - clen) < TOL)
            {
                result = g.EC;
                return(true);
            }

            // Get the bearing of the BC
            ICircleGeometry circle  = g.Circle;
            IPosition       c       = circle.Center;
            double          radius  = circle.Radius;
            double          bearing = BasicGeom.BearingInRadians(c, g.BC);

            // Add the angle that subtends the required distance (or
            // subtract if the curve goes anti-clockwise).
            if (g.IsClockwise)
            {
                bearing += (d / radius);
            }
            else
            {
                bearing -= (d / radius);
            }

            // Figure out the required point from the new bearing.
            result = BasicGeom.Polar(c, bearing, radius);
            return(true);
        }