using System; using System.Collections.Generic; using System.Numerics; using Manager; namespace AquaMai.MaimaiDX2077; public static class MaiGeometry { public struct CircleStruct(Complex center, double radius) { public Complex Center = center; public double Radius = radius; } public static readonly double CanvasWidth = 1080.0; public static readonly double MainRadius = 480.0; public static readonly double CenterRadius = MainRadius * Math.Cos(Math.PI * 3 / 8); public static readonly double GroupBRadius = CenterRadius / Math.Cos(Math.PI / 8); private static readonly double _b = Math.Cos(Math.PI / 8) / 2; private static readonly double _a = 1 - _b; private static readonly double _theta = Math.PI / 4; private static readonly double _s = (_a * _a + _b * _b - 2 * _a * _b * Math.Cos(_theta)) / (2 * _a - 2 * _b * Math.Cos(_theta)); public static readonly double PPQQRadius = MainRadius * _b; public static readonly double TransferRadius = MainRadius * (_b + _s); public static readonly double EdgeTransferAngle = _theta; public static readonly double PPQQTransferAngle = Math.Acos((_s * _s + _b * _b - (_a - _s) * (_a - _s)) / (2 * _b * _s)); public static readonly double DefaultDistance = MainRadius * Math.PI / 32; public static readonly int[,] MirrorInfo = new int[4, 17] { { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }, // Normal { 7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8, 16 }, // L <-> R { 3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12, 16 }, // U <-> D { 4, 5, 6, 7, 0, 1, 2, 3, 12, 13, 14, 15, 8, 9, 10, 11, 16 } // rotate 180 deg }; /// /// Note: idx is 1-based, not 0-based /// public static Complex PointGroupA(int idx) { var angle = Math.PI * (5.0 / 8.0 - idx / 4.0); return Complex.FromPolarCoordinates(MainRadius, angle); } /// /// Note: idx is 1-based, not 0-based /// public static Complex PointGroupB(int idx) { var angle = Math.PI * (5.0 / 8.0 - idx / 4.0); return Complex.FromPolarCoordinates(GroupBRadius, angle); } public static Complex Center() { return Complex.Zero; } /// /// idx 0 is center circle, idx 1~8 are ppqq circles, idx 9 is outer circle /// public static CircleStruct GetCircle(int idx) { if (idx == 0) { return new CircleStruct(Complex.Zero, CenterRadius); } if (idx == 9) { return new CircleStruct(Complex.Zero, MainRadius); } var angle = Math.PI * (3.0 / 4.0 - idx / 4.0); var center = Complex.FromPolarCoordinates(PPQQRadius, angle); return new CircleStruct(center, PPQQRadius); } /// /// Note: idx is 1-based, not 0-based /// /// CircleStruct TransferCircle, double TransferStartAngle, double TransferEndAngle public static Tuple TransferOutData(int idx, bool isccw) { var ppqqRad = Math.PI * (3.0 / 4.0 - idx / 4.0); double startAngle, endAngle; if (isccw) { startAngle = ppqqRad - PPQQTransferAngle; endAngle = ppqqRad + EdgeTransferAngle; } else { startAngle = ppqqRad + PPQQTransferAngle; endAngle = ppqqRad - EdgeTransferAngle; } var d = MainRadius - TransferRadius; var center = Complex.FromPolarCoordinates(d, endAngle); return new Tuple(new CircleStruct(center, TransferRadius), Math.IEEERemainder(startAngle, Math.PI * 2), Math.IEEERemainder(endAngle, Math.PI * 2)); } }