XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFEEDToolBox

【WinUI】XFE精英危险工具箱

公开
关注 0 Fork 0 Star 0
UTF-8
using XFEEDToolBox.Core.Navigation;

namespace XFEEDToolBox.Core.Rendering;

public sealed record LocalSystemMarkerGroup(LocalSystemProjection Anchor,IReadOnlyList<LocalSystemProjection> Members);

/// <summary>Declutters only destination markers. No physical model or orbital point is moved.</summary>
public static class LocalSystemMarkerLayout
{
    public static bool Celestial(SystemLocation location)=>location.Category is SystemLocationCategory.Star or SystemLocationCategory.Planet or SystemLocationCategory.LandablePlanet;
    public static IReadOnlyList<LocalSystemMarkerGroup> Build(IReadOnlyList<LocalSystemProjection> all,IReadOnlyList<LocalSystemProjection> visible)
    {
        var groups=new List<(LocalSystemProjection Anchor,List<LocalSystemProjection> Members)>();
        var bodies=all.Where(point=>Celestial(point.Node.Location)).OrderByDescending(point=>point.Radius).ToArray();
        foreach(var point in visible.Where(point=>!Celestial(point.Node.Location)).OrderByDescending(point=>point.Selected).ThenBy(point=>point.Depth))
        {
            var x=point.X;var y=point.Y;
            foreach(var body in bodies)
            {
                var dx=x-body.X;var dy=y-body.Y;var distance=Math.Sqrt(dx*dx+dy*dy);var radius=body.Radius+20;
                if(distance>=radius)continue;
                if(distance<1){var angle=point.Node.Location.Key*2.399963229728653;dx=Math.Cos(angle);dy=Math.Sin(angle);distance=1;}
                x=body.X+dx/distance*radius;y=body.Y+dy/distance*radius;
            }
            var anchor=point with{X=x,Y=y,Radius=12};
            var index=groups.FindIndex(group=>Math.Pow(group.Anchor.X-x,2)+Math.Pow(group.Anchor.Y-y,2)<30*30);
            if(index<0)groups.Add((anchor,[point]));else groups[index].Members.Add(point);
        }
        return groups.Select(group=>new LocalSystemMarkerGroup(group.Anchor,group.Members)).ToArray();
    }
}