private LayoutResult FindBestLayout(
int hexCount,
Vector2 planeSize,
Vector2 baseHexSize)
{
LayoutResult bestLayout = default;
float bestScore = float.NegativeInfinity;
if (planeSize.x <= Mathf.Epsilon ||
planeSize.y <= Mathf.Epsilon ||
baseHexSize.x <= Mathf.Epsilon ||
baseHexSize.y <= Mathf.Epsilon)
{
return bestLayout;
}
float planeAspect = planeSize.x / planeSize.y;
for (int rowCount = 1; rowCount <= hexCount; rowCount++)
{
int[] rowHexCounts = BuildRowHexCounts(hexCount, rowCount);
Vector2[] centers = BuildCenters(rowHexCounts, baseHexSize);
LayoutBounds layoutBounds = CalculateLayoutBounds(centers, baseHexSize);
float scaleByWidth = planeSize.x / layoutBounds.Size.x;
float scaleByDepth = planeSize.y / layoutBounds.Size.y;
float scale = Mathf.Min(scaleByWidth, scaleByDepth);
float usedWidth = layoutBounds.Size.x * scale;
float usedDepth = layoutBounds.Size.y * scale;
float fillWidth = usedWidth / planeSize.x;
float fillDepth = usedDepth / planeSize.y;
float areaFill = fillWidth * fillDepth;
float layoutAspect = layoutBounds.Size.x / layoutBounds.Size.y;
float aspectDifference = Mathf.Abs(Mathf.Log(layoutAspect / planeAspect));
float aspectPenalty = 1f / (1f + aspectDifference);
float score = areaFill * aspectPenalty;
if (!bestLayout.IsValid || score > bestScore)
{
bestScore = score;
bestLayout = new LayoutResult(
centers,
layoutBounds.Center,
scale);
}
}
return bestLayout;
}