64 lines
2.0 KiB
C#
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)
|
||
|
{
|
||
|
}
|
||
|
}
|