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; }