2DLightPathSimulator/LensSimulatorCore/Optical/SphericalSurface.cs

64 lines
2.0 KiB
C#

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);
}
/// <summary>
/// Generates a PolyLine, which can be merged with another to make a full element shape.
/// </summary>
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)
{
}
}