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; }
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)); }
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; }
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; }
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; }
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); }
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 { } /* */ }