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();
}
}
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();
}
}