예제 #1
0
        public rm21HorArc(ptsPoint begPt, ptsPoint endPt, Azimuth incomingAzimuth, Double radius)
            : base(begPt, endPt)
        {
            if (0 == utilFunctions.tolerantCompare((endPt - begPt).Length, 0.0, 0.000001))
            throw new ArcExceptionZeroLengthNotDefined();

             Double tanOffsetToEndPt;
             ptsRay incomingRay = new ptsRay(); incomingRay.advanceDirection = 1;
             incomingRay.StartPoint = begPt; incomingRay.HorizontalDirection = incomingAzimuth;
             tanOffsetToEndPt = incomingRay.getOffset(endPt);

             if (0 == utilFunctions.tolerantCompare(tanOffsetToEndPt, 0.0, 0.000001))
            throw new ArcExceptionZeroDeflectionNotDefined();

             this.BeginStation = 0.0;
             this.Radius = radius;
             this.BeginAzimuth = incomingAzimuth;

             deflDirection = Math.Sign(tanOffsetToEndPt);
             Deflection defl = Deflection.ctorDeflectionFromAngle(90.0, deflDirection);
             Azimuth azToCenter = incomingAzimuth + defl;
             ptsVector traverseToCenterVec = new ptsVector(azToCenter, radius);
             ArcCenterPt = begPt + traverseToCenterVec;

             this.BeginRadiusVector = this.ArcCenterPt - this.BeginPoint;
             Azimuth endVecAz = (this.ArcCenterPt - endPt).Azimuth;
             this.EndRadiusVector = new ptsVector(endVecAz, radius);
             this.EndPoint = this.ArcCenterPt + this.EndRadiusVector;

             var deflectionDbl = endVecAz - this.BeginRadiusVector.Azimuth;
             this.Deflection = new Deflection(deflectionDbl, deflDirection);
             this.EndAzimuth = this.BeginAzimuth + this.Deflection;

             // applies to English projects only (for now)
             this.BeginDegreeOfCurve = HorizontalAlignmentBase.computeDegreeOfCurve(this.Radius);
             this.EndDegreeOfCurve = this.BeginDegreeOfCurve;

             this.Length = 100.0 * this.Deflection.getAsRadians() / this.BeginDegreeOfCurve.getAsRadians();
             this.Length = Math.Abs(this.Length);
             this.EndStation = this.BeginStation + this.Length;
        }
예제 #2
0
        public override void moveToOuterEdge(ref StationOffsetElevation aSOE, int whichSide)
        {
            //double traversedWidth;
             double? theWidth;
             tupleNullableDoubles result;
             double? theCrossSlope = getCrossSlope((CogoStation)aSOE.station, out result);
             if (result.isSingleValue == false)
             {
            if (result.ahead != null)
            {
               theCrossSlope = result.ahead;
            }
            else if (result.back != null)
            {
               theCrossSlope = result.back;
            }
            else
            {
               throw new NotImplementedException("Width discontinuity is not allowed. This happens at station = " + aSOE.station);
            }
             }

             ptsRay thisAsRay = new ptsRay();
             thisAsRay.StartPoint = new ptsPoint(aSOE.offset, 0.0, aSOE.elevation);
             thisAsRay.Slope = (double)theCrossSlope;
             thisAsRay.advanceDirection = whichSide;
             Profile rayAsProfile = this.MyParentPGLgrouping.ParentCorridor.existingGroundProfile.getIntersections(thisAsRay).FirstOrDefault<Profile>();

             theWidth = Math.Abs(rayAsProfile.EndProfTrueStation - rayAsProfile.BeginProfTrueStation);
             if (theWidth == null) theWidth = 0.0;

             aSOE.offset += theWidth * whichSide;

             if (theCrossSlope == null) theCrossSlope = 0.0;
             aSOE.elevation += theCrossSlope * theWidth;
        }
        public void appendTangent(ptsPoint TangentEndPoint)
        {
            // See "Solving SSA triangles"
             // http://www.mathsisfun.com/algebra/trig-solving-ssa-triangles.html

             var lastChainItem = allChildSegments.Last();
             if (!(lastChainItem is rm21HorArc))
            throw new Exception("Can't add tangent on a tangent segment.");

             var finalArc = lastChainItem as rm21HorArc;

             var incomingTanRay = new ptsRay(); incomingTanRay.StartPoint = finalArc.BeginPoint;
             incomingTanRay.HorizontalDirection = finalArc.BeginAzimuth;
             int offsetSide = Math.Sign(incomingTanRay.getOffset(TangentEndPoint));
             double rad = finalArc.Radius;
             Azimuth traverseToRevisedCenterPtAzimuth = finalArc.BeginAzimuth + offsetSide * Math.PI/2.0;
             ptsVector traverseToRevisedCenterPt = new ptsVector(traverseToRevisedCenterPtAzimuth, rad);
             ptsPoint revCenterPt = finalArc.BeginPoint + traverseToRevisedCenterPt;

             ptsVector ccToTEPvec = finalArc.ArcCenterPt - TangentEndPoint;

             ptsAngle rho = Math.Asin(rad / ccToTEPvec.Length);
             ptsAngle ninetyDegrees = new ptsAngle();
             ninetyDegrees.setFromDegreesDouble(90.0);
             ptsAngle tau = ninetyDegrees - rho;

             Azimuth ccToPtVecAz = ccToTEPvec.Azimuth;
             Azimuth arcBegRadAz = finalArc.BeginRadiusVector.Azimuth;

             ptsCogo.Angle.Deflection outerDefl = ccToPtVecAz.minus(arcBegRadAz);
             ptsDegree  defl = Math.Abs((tau - outerDefl).getAsDegreesDouble()) * offsetSide;
             Deflection newDeflection = new Deflection(defl.getAsRadians());
             finalArc.setDeflection(newDeflection: newDeflection);

             var appendedLineSegment = new rm21HorLineSegment(finalArc.EndPoint, TangentEndPoint);
             appendedLineSegment.BeginStation = finalArc.EndStation;
             appendedLineSegment.Parent = this;
             allChildSegments.Add(appendedLineSegment);

             this.EndAzimuth = appendedLineSegment.EndAzimuth;
             this.EndPoint = appendedLineSegment.EndPoint;
             restationAlignment();

             if (alignmentData.Count > 0)
            alignmentData.RemoveAt(alignmentData.Count-1);
             alignmentData.Add(new alignmentDataPacket(alignmentData.Count, finalArc));
             alignmentData.Add(new alignmentDataPacket(alignmentData.Count, appendedLineSegment));
        }
예제 #4
0
        public List<Profile> getIntersections(ptsRay aRay)
        {
            if (true == aRay.Slope.isVertical())
            return this.verticalRayGetIntersection(aRay);

             int advanceDirection = aRay.advanceDirection;
             List<Profile> returnList = null;

             if ((advanceDirection < 0) && (aRay.StartPoint.x < allVCs[0].BeginStation.trueStation))
            return null;

             if ((advanceDirection > 0) && (aRay.StartPoint.x > allVCs[allVCs.Count-1].EndStation.trueStation))
            return null;

             int i = -1;
             while (++i < this.allVCs.Count)
             {
            var profSeg = allVCs[i];

            if (true == profSeg.shouldComputeThisIntersection(aRay.StartPoint.x, advanceDirection))
            {
               List<List<verticalCurve>> resultingVCs = profSeg.getRayIntersections(aRay);
               if (null != resultingVCs)
               {
                  if (null == returnList)
                     returnList = new List<Profile>();
                  foreach (var resultingVC in resultingVCs)
                     returnList.Add(new Profile(resultingVC));
               }
            }

             }

             if (null != returnList)
             {
            return returnList.OrderBy<Profile, double>(pfl => Math.Abs(pfl.BeginProfTrueStation - pfl.EndProfTrueStation)).ToList<Profile>();
             }

             return null;
        }
예제 #5
0
            private List<verticalCurve> getRayIntersectionsOnTangentSegment(ptsRay aRay)
            {
                if (this.slopeRateOfChange_ != Double.PositiveInfinity)
                   throw new Exception("Parabolic profile segment encountered where tangent profile segment expected.");

                if (aRay.get_m() == this.get_m())
                {
                   if (this.get_b() == aRay.get_b())
                  return null;
                   else
                  throw new NotImplementedException();
                }

                double intersectionX = (this.get_b() - aRay.get_b()) /
                                   (aRay.get_m() - this.get_m());

                if (intersectionX < this.BeginStation.trueStation || intersectionX > this.EndStation.trueStation)
                   return null;

                if (false == aRay.isWithinDomain(intersectionX))
                   return null;

                int sign = 1;
                verticalCurve newVC = null;
                if (1 == aRay.advanceDirection)
                {
                   newVC = new verticalCurve((CogoStation)aRay.StartPoint.x, aRay.StartPoint.z,
                  aRay.Slope, intersectionX - aRay.StartPoint.x, Double.PositiveInfinity);
                }
                else
                {
                   sign = -1;
                   newVC = new verticalCurve((CogoStation)intersectionX, getElevation(this, (CogoStation)intersectionX),
                  sign * aRay.Slope, Math.Abs(intersectionX - aRay.StartPoint.x), Double.PositiveInfinity);
                }
                var returnList = new List<verticalCurve>();
                returnList.Add(newVC);
                return returnList;
            }
예제 #6
0
            private List<List<verticalCurve>> getRayIntersectionsOnParabolicSegment(ptsRay aRay)
            {
                List<List<verticalCurve>> returnListOfLists = null;
                double xForZeroSlope = getXforSlopeZero();
                var parabola0_0point = new { x = xForZeroSlope, elev = getElevation(this, (CogoStation) xForZeroSlope) };

                /* in which m is slope of the ray, b is the y-intercept of the ray
                 * from y = mx + b
                 * k is the slope rate of change of the parabola
                 * from y = kx^2
                 * Solved into a quadratic equation, it is in the form of
                 * -kx^2 + mx + b = 0
                 *
                 * which then is solved by the quadratic formula:
                 *       -m +/- sqrt(m^2 + 4kb)
                 * x =   ----------------------
                 *              -2k
                 *
                 * Finally, the part under the square root is called the discriminant.
                 * If the discriminant is negative, the roots are imaginary and
                 * we have no interest in those for our application.  - Paul Schrum
                 * http://en.wikipedia.org/wiki/Quadratic_equation
                 * */

                // Ray parts
                double m = aRay.get_m();
                double untransformedB = aRay.get_b();
                double rayElevAtParabolaInflectionStation = (m * parabola0_0point.x) + untransformedB;
                double b = rayElevAtParabolaInflectionStation - parabola0_0point.elev;

                // parabola parts
                double k = this.slopeRateOfChange_ / 2.0;

                double discriminant = (m * m) + (4 * k * b);
                if (discriminant < 0.0)
                   return null;

                double sqrtDisc = Math.Sqrt(discriminant);
                double xIntercept1;
                double xIntercept2;

                int sign = 1;
                verticalCurve newVC = null;

                xIntercept1 = ((-m + sqrtDisc) / (-2 * k)) + parabola0_0point.x;
                if (true == aRay.isWithinDomain(xIntercept1) && true == this.isWithinDomain(xIntercept1))
                {
                   if (1 == aRay.advanceDirection)
                  newVC = new verticalCurve((CogoStation)aRay.StartPoint.x, aRay.StartPoint.z,
                     aRay.Slope, xIntercept1 - aRay.StartPoint.x, Double.PositiveInfinity);
                   else
                   {
                  sign = -1;
                  newVC = new verticalCurve((CogoStation) xIntercept1, getElevation(this, (CogoStation)xIntercept1),
                     sign * aRay.Slope, Math.Abs(xIntercept1 - aRay.StartPoint.x), Double.PositiveInfinity);
                   }
                   if (null == returnListOfLists)
                  returnListOfLists = new List<List<verticalCurve>>();

                   List<verticalCurve> listOfVerticalCurves = new List<verticalCurve>();
                   listOfVerticalCurves.Add(newVC);
                   returnListOfLists.Add(listOfVerticalCurves);
                }

                if (discriminant > 0)
                {
                   xIntercept2 = ((-m - sqrtDisc) / (-2 * k)) + parabola0_0point.x;
                   if (true == aRay.isWithinDomain(xIntercept2) && true == this.isWithinDomain(xIntercept2))
                   {
                  if (1 == aRay.advanceDirection)
                  {
                     sign = 1;
                     newVC = new verticalCurve((CogoStation)aRay.StartPoint.x, aRay.StartPoint.z,
                        aRay.Slope, xIntercept2 - aRay.StartPoint.x, Double.PositiveInfinity);
                  }
                  else
                  {
                     sign = -1;
                     newVC = new verticalCurve((CogoStation)xIntercept2, getElevation(this, (CogoStation)xIntercept2),
                        sign * aRay.Slope, Math.Abs(xIntercept2 - aRay.StartPoint.x), Double.PositiveInfinity);
                  }
                  if (null == returnListOfLists)
                     returnListOfLists = new List<List<verticalCurve>>();

                  List<verticalCurve> listOfVerticalCurves = new List<verticalCurve>();
                  listOfVerticalCurves.Add(newVC);
                  returnListOfLists.Add(listOfVerticalCurves);
                   }
                }

                return returnListOfLists;
            }
예제 #7
0
 public List<List<verticalCurve>> getRayIntersections(ptsRay aRay)
 {
     if (true == this.IsTangent)
     {
        List<verticalCurve> aList = getRayIntersectionsOnTangentSegment(aRay);
        if (null == aList)
       return null;
        else
        {
       var returnListOfLists = new List<List<verticalCurve>>();
       returnListOfLists.Add(aList);
       return returnListOfLists;
        }
     }
     else
        return getRayIntersectionsOnParabolicSegment(aRay);
 }
예제 #8
0
        private List<Profile> verticalRayGetIntersection(ptsRay aRay)
        {
            double? elevOnProfile = this.getElevation((CogoStation)(aRay.StartPoint.x));
             if (elevOnProfile == null)
            return null;

             return null;
             // ToDo: figure out what to do about vertical profile segments
             /* * /
             double elevDiff = aRay.StartPoint.z - (double)elevOnProfile;

             Profile retPfl = null;
             if (true == aRay.Slope.isSlopeUp())
             {
            if (elevDiff > 0.0)
               return null;
            retPfl = new Profile(;
             }
             else
             {

             }  /* */
        }