using LensSimulatorCore.Shapes; namespace LensSimulatorCore.Optical; internal abstract class SphericalSurface : Surface { protected Circle face; public override void UpdateSurfacePositions() { SideSign = IsFront ? -1 : 1; QuadraticSign = IsFront ? -1 * Math.Sign(face.Radius) : 1 * Math.Sign(face.Radius); face.Position = new Point((IsFront ? 1 : -1) * (face.Radius - (Parent.Depth / 2)), 0); } public override Point FindIntersection(PointVector pointVector) { //Convert point vector to a line. var line = pointVector.ToLine(); var xs2 = (face.Position.X * -2); var ys2 = (face.Position.Y * -2); double a, b, c; //Creates a quadratic formula via substitution of a Line and a Circle equation. a = 1 + (Math.Pow(line.B, 2)); b = xs2 + (ys2 * line.B) + (line.B * line.C * 2); c = Math.Pow(line.C, 2) + (line.C * ys2) + Math.Pow(face.Position.X * -1, 2) + Math.Pow(face.Position.Y * -1, 2) - Math.Pow(face.Radius, 2); var x = (-b + QuadraticSign * Math.Sqrt(Math.Pow(b, 2) - 4 * a * c)) / (2 * a); var y = (x * line.B) + line.C; return new Point(x, y); } /// /// Generates a PolyLine, which can be merged with another to make a full element shape. /// public override void GeneratePolyLine() { const int resolution = 80; var arcTotalSweep = Math.Asin((Parent.Diameter / 2) / face.Radius) * 2; var arcResolutionSweep = arcTotalSweep / (resolution - 1); var arcCentre = new Point(face.Position.X, face.Position.Y); for (var i = 0; i < resolution; i++) { var currentAngle = (SideSign * arcTotalSweep / 2) + -SideSign * (arcResolutionSweep * i); var x = Math.Cos(currentAngle) * SideSign * face.Radius + arcCentre.X; var y = Math.Sin(currentAngle) * face.Radius; PolyLine.Add(new Point(x, y)); } } protected SphericalSurface(Element parent) : base(parent) { } }