Exemple #1
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);
        }
Exemple #2
0
        /// <summary>
        /// Obtains annotation for this line.
        /// </summary>
        /// <param name="dist">The observed distance (if any).</param>
        /// <param name="drawObserved">Draw observed distance? Specify <c>false</c> for
        /// actual distance.</param>
        /// <returns>The annotation (null if it cannot be obtained)</returns>
        Annotation GetAnnotation(Distance dist, bool drawObserved)
        {
            // @devnote This function may not be that hot for curves that
            // are complete circles. At the moment though, I can't see why
            // we'd be drawing a distance alongside a circle.

            // Get the length of the arc
            double len = this.Length.Meters;

            // Get the string to output.
            string distr = GetDistance(len, dist, drawObserved);

            if (distr == null)
            {
                return(null);
            }

            // Get the mid-point of this arc.
            IPosition mid;

            this.GetPosition(new Length(len * 0.5), out mid);

            // Get the bearing from the center to the midpoint.
            IPosition center  = m_Circle.Center;
            double    bearing = BasicGeom.BearingInRadians(center, mid);

            // Get the height of the text, in meters on the ground.
            double grheight = EditingController.Current.LineAnnotationStyle.Height;

            // We will offset by 20% of the height (give a bit of space
            // between the text and the line).
            //double offset = grheight * 0.2;
            // ...looks fine with no offset (there is a space, but it's for descenders
            // that aren't there since we're dealing just with numbers).
            double offset = 0.0;

            // Get the rotation of the text.
            double rotation = bearing - MathConstants.PI;

            // If the midpoint is above the circle centre, we get upside-down
            // text so rotate it the other way. If we don't switch the
            // rotation, we need to make an extra shift, because the text
            // is aligned along its baseline.

            // This depends on whether the annotation is on the default
            // side or not.

            // Not sure about the following... (c.f. revised handling in SegmentGeometry)

            /*
             * if (mid.Y > center.Y)
             * {
             *  rotation += MathConstants.PI;
             *  if (isFlipped)
             *      offset = -0.9 * grheight;
             * }
             * else
             * {
             *  if (isFlipped)
             *      offset = -offset;
             *  else
             *      offset = 0.9 * grheight;	// 1.0 * grheight is too much
             * }
             */

            // ...try this instead

            if (mid.Y > center.Y)
            {
                rotation += MathConstants.PI;
            }
            else
            {
                offset = 1.3 * grheight; // push the text to the outer edge of the arc
            }
            if (dist != null && dist.IsAnnotationFlipped)
            {
                rotation += MathConstants.PI;

                // and may need to adjust offset...
            }

            // Project to the offset point.
            IPosition  p      = Geom.Polar(center, bearing, m_Circle.Radius + offset);
            Annotation result = new Annotation(distr, p, grheight, rotation);

            result.FontStyle = FontStyle.Italic;
            return(result);
        }
Exemple #3
0
 public static double GetStartBearingInRadians(ICircularArcGeometry g)
 {
     return(BasicGeom.BearingInRadians(g.Circle.Center, g.First));
 }