/// <summary> /// Obtains line sections for a specific face in this path. /// </summary> /// <param name="face">The face of interest</param> /// <returns>The corresponding sections</returns> internal ILineGeometry[] GetSections(LegFace face) { EnsureAdjusted(); // Initialize position to the start of the path. IPosition p = new Position(m_From); // Initial bearing is whatever the rotation is. double bearing = m_Rotation; // Get the position at the start of the required leg. foreach (Leg leg in m_Legs) { if (leg == face.Leg) { break; } leg.Project(ref p, ref bearing, m_ScaleFactor); } // We've now got the position at the start of the required leg, and the bearing of the previous leg. // If the leg we actually want if a straight leg (or an extra leg layered on a straight), add on any // initial angle. StraightLeg sLeg = (face.Leg as StraightLeg); if (sLeg != null) { bearing = sLeg.AddStartAngle(bearing); } return(face.Leg.GetSpanSections(p, bearing, m_ScaleFactor, face.Spans)); }
/// <summary> /// Draws the path on the specified display /// </summary> /// <param name="display">The display to draw to</param> internal void Render(ISpatialDisplay display) { EnsureAdjusted(); // Do nothing if the scale factor is undefined. if (Math.Abs(m_ScaleFactor) < MathConstants.TINY) { return; } // Initialize position to the start of the path. IPosition gotend = new Position(m_From); // Initial bearing is whatever the rotation is. double bearing = m_Rotation; for (int i = 0; i < m_Legs.Length; i++) { Leg leg = m_Legs[i]; // Include any angle specified at the start of the leg StraightLeg sLeg = (leg as StraightLeg); if (sLeg != null) { bearing = sLeg.AddStartAngle(bearing); } // Determine exit bearing for circular leg (do it now, in case an extra leg complicates matters below) double exitBearing = bearing; CircularLeg cLeg = (leg as CircularLeg); if (cLeg != null) { exitBearing = cLeg.GetExitBearing(gotend, bearing, m_ScaleFactor); } // Obtain geometry for each span and draw SpanInfo[] spans = leg.PrimaryFace.Spans; ILineGeometry[] sections = leg.GetSpanSections(gotend, bearing, m_ScaleFactor, spans); DrawSpans(display, spans, sections); // If we're dealing with the first face of a staggered leg, process the second face if (leg.AlternateFace != null) { spans = leg.AlternateFace.Spans; sections = leg.GetSpanSections(gotend, bearing, m_ScaleFactor, spans); DrawSpans(display, spans, sections); } // Get to the end of the leg gotend = sections[sections.Length - 1].End; bearing = exitBearing; } // Re-draw the terminal points to ensure that their color is on top. DrawEnds(display); }
/* * // @mfunc Create transient CeMiscText objects for any observed * // angles that are part of this leg. * // * // The caller is responsible for deleting the text * // objects once done with them. * // * // @parm The point the observation must be made from. * // Specify 0 for all points. * // @parm The operation this leg belongs to. * // @parm Scale factor to apply to the leg. * // @parm The position of a backsight prior to the BC (may * // be undefined). * // @parm The position of the start of the leg. * // @parm The bearing to the start of the leg. Updated to * // refer to the bearing to the end of the leg. * // @parm The position of the end of the leg. * // @parm List of pointers to created text objects (appended to). * // @parm Should lines be produced too? * // * // @rdesc TRUE if the specified from point was encountered (this * // does not necessarily mean that any text needed to be * // generated for it). * * LOGICAL CeStraightLeg::CreateAngleText ( const CePoint* const pFrom * , const CeOperation& op * , const FLOAT8 sfac * , const CeVertex& bs * , const CeVertex& from * , FLOAT8& bearing * , CeVertex& to * , CPtrList& text * , const LOGICAL wantLinesToo ) const { * * // Project to the end of the leg. * to = from; * this->Project(to,bearing,sfac); * * // If a from point has been specified, and this leg does * // not start at it, just return. * if ( pFrom && GetpStartPoint(op)!=pFrom ) return FALSE; * * // Return if this leg does not have an initial angle. * const FLOAT8 angle = fabs(m_StartAngle); * if ( angle<TINY ) return TRUE; * * // Return if the angle is real-close to a right angle * if ( fabs(angle-PIDIV2 )<0.000001 || * fabs(angle-PIMUL1P5)<0.000001 ) return TRUE; * * // Create the text. * MakeText(bs,from,to,m_StartAngle,text); * * return TRUE; * * } // end of CreateAngleText */ /// <summary> /// Breaks this leg into two legs. The break must leave at least /// one distance in each of the resultant legs. /// </summary> /// <param name="index">The index of the span that should be at the /// start of the extra leg.</param> /// <returns>The extra leg (at the end of the original leg).</returns> internal StraightLeg Break(int index) { if (this.AlternateFace != null) { throw new InvalidOperationException("Cannot break a staggered leg"); } // Can't break right at the start or end. int nTotal = PrimaryFace.Count; if (index <= 0 || index >= nTotal) { return(null); } // Create a new straight leg with the right number of spans. StraightLeg newLeg = new StraightLeg(PrimaryFace, index); // Retain the spans prior to that PrimaryFace.TruncateLeg(index); return(newLeg); }
/// <summary> /// Creates a straight leg. /// </summary> /// <param name="items">Array of path items.</param> /// <param name="si">Index to the item where the leg data starts.</param> /// <param name="nexti">Index of the item where the next leg starts.</param> /// <returns>The new leg.</returns> static StraightLeg CreateStraightLeg(PathItem[] items, int si, out int nexti) { // Get the leg ID. int legnum = items[si].LegNumber; // How many distances have we got? int ndist = 0; for (nexti = si; nexti < items.Length && items[nexti].LegNumber == legnum; nexti++) { if (items[nexti].IsDistance) ndist++; } // Create the leg. StraightLeg leg = new StraightLeg(ndist); // Assign each distance. ndist = 0; for (int i = si; i < nexti; i++) { Distance d = items[i].GetDistance(); if (d != null) { // See if there is a qualifier after the distance LegItemFlag qual = LegItemFlag.Null; if ((i + 1) < nexti) { PathItemType nexttype = items[i + 1].ItemType; if (nexttype == PathItemType.MissConnect) qual = LegItemFlag.MissConnect; if (nexttype == PathItemType.OmitPoint) qual = LegItemFlag.OmitPoint; } leg.PrimaryFace.SetDistance(d, ndist, qual); ndist++; } } // If the first item is an angle, remember it as part of the leg. if (items[si].ItemType == PathItemType.Angle) leg.StartAngle = items[si].Value; else if (items[si].ItemType == PathItemType.Deflection) leg.SetDeflection(items[si].Value); // Return a reference to the new leg return leg; }
/* // @mfunc Create transient CeMiscText objects for any observed // angles that are part of this leg. // // The caller is responsible for deleting the text // objects once done with them. // // @parm The point the observation must be made from. // Specify 0 for all points. // @parm The operation this leg belongs to. // @parm Scale factor to apply to the leg. // @parm The position of a backsight prior to the BC (may // be undefined). // @parm The position of the start of the leg. // @parm The bearing to the start of the leg. Updated to // refer to the bearing to the end of the leg. // @parm The position of the end of the leg. // @parm List of pointers to created text objects (appended to). // @parm Should lines be produced too? // // @rdesc TRUE if the specified from point was encountered (this // does not necessarily mean that any text needed to be // generated for it). LOGICAL CeStraightLeg::CreateAngleText ( const CePoint* const pFrom , const CeOperation& op , const FLOAT8 sfac , const CeVertex& bs , const CeVertex& from , FLOAT8& bearing , CeVertex& to , CPtrList& text , const LOGICAL wantLinesToo ) const { // Project to the end of the leg. to = from; this->Project(to,bearing,sfac); // If a from point has been specified, and this leg does // not start at it, just return. if ( pFrom && GetpStartPoint(op)!=pFrom ) return FALSE; // Return if this leg does not have an initial angle. const FLOAT8 angle = fabs(m_StartAngle); if ( angle<TINY ) return TRUE; // Return if the angle is real-close to a right angle if ( fabs(angle-PIDIV2 )<0.000001 || fabs(angle-PIMUL1P5)<0.000001 ) return TRUE; // Create the text. MakeText(bs,from,to,m_StartAngle,text); return TRUE; } // end of CreateAngleText */ /// <summary> /// Breaks this leg into two legs. The break must leave at least /// one distance in each of the resultant legs. /// </summary> /// <param name="index">The index of the span that should be at the /// start of the extra leg.</param> /// <returns>The extra leg (at the end of the original leg).</returns> internal StraightLeg Break(int index) { if (this.AlternateFace != null) throw new InvalidOperationException("Cannot break a staggered leg"); // Can't break right at the start or end. int nTotal = PrimaryFace.Count; if (index <= 0 || index >= nTotal) return null; // Create a new straight leg with the right number of spans. StraightLeg newLeg = new StraightLeg(PrimaryFace, index); // Retain the spans prior to that PrimaryFace.TruncateLeg(index); return newLeg; }
/// <summary> /// Creates a straight leg. /// </summary> /// <param name="items">Array of path items.</param> /// <param name="si">Index to the item where the leg data starts.</param> /// <param name="nexti">Index of the item where the next leg starts.</param> /// <returns>The new leg.</returns> static StraightLeg CreateStraightLeg(PathItem[] items, int si, out int nexti) { // Get the leg ID. int legnum = items[si].LegNumber; // How many distances have we got? int ndist = 0; for (nexti = si; nexti < items.Length && items[nexti].LegNumber == legnum; nexti++) { if (items[nexti].IsDistance) { ndist++; } } // Create the leg. StraightLeg leg = new StraightLeg(ndist); // Assign each distance. ndist = 0; for (int i = si; i < nexti; i++) { Distance d = items[i].GetDistance(); if (d != null) { // See if there is a qualifier after the distance LegItemFlag qual = LegItemFlag.Null; if ((i + 1) < nexti) { PathItemType nexttype = items[i + 1].ItemType; if (nexttype == PathItemType.MissConnect) { qual = LegItemFlag.MissConnect; } if (nexttype == PathItemType.OmitPoint) { qual = LegItemFlag.OmitPoint; } } leg.PrimaryFace.SetDistance(d, ndist, qual); ndist++; } } // If the first item is an angle, remember it as part of the leg. if (items[si].ItemType == PathItemType.Angle) { leg.StartAngle = items[si].Value; } else if (items[si].ItemType == PathItemType.Deflection) { leg.SetDeflection(items[si].Value); } // Return a reference to the new leg return(leg); }