>想象一下,我有一个由规范化位置(t)和宽度组成的实体数组。
struct Entity
{
float t; // left position as a percentage of the parent's size
float width; // width of the entity in absolute values
}
一旦我决定了父级的大小,我可以轻松地像这样渲染所有实体:
void Draw(Entity[] entities, float size)
{
foreach(var entity in entities)
{
var x = entity.t * size;
Draw(x, entity.width); // x corresponds to left side, not center
}
}
我很难弄清楚如何计算最小size
对于任何给定的实体集,允许它们在不相交边界的情况下渲染。
如果您对此操作的用例感到好奇,它是一个辅助函数,我需要解决乐谱渲染系统上的一些边缘情况。和弦标签放置在乐谱顶部的布局周期结束时,它们的位置需要与相应的音乐内容正确对齐。但在某些情况下,满足此约束意味着度量值上没有足够的空间来适应标签。我需要这个函数来提前确定是否没有足够的空间,如果没有,请要求度量值按缺失的数量增长。
如果您不想移动标签,即t
应该始终位于标签的左端位置,我认为这个简单的代码可以满足您的需求
static float CalcMinWidth(IList<Entity> entities)
{
var count = entities.Count;
List<Entity> local = new List<Entity>(count + 1);
local.AddRange(entities);
local.Add(new Entity(1, 0)); // add one that marks "end"
local.Sort((e1, e2) => Comparer<float>.Default.Compare(e1.t, e2.t));
float minReqW = 0;
for (int i = 0; i < count; i++)
{
var e1 = local[i];
var e2 = local[i + 1];
var reqW = e1.width / (e2.t - e1.t);
if (reqW > minReqW)
minReqW = reqW;
}
return minReqW;
}
这个想法是,最小宽度由某个特定的实体e1
指定,该实体不应与下一个实体e2
重叠(或在代码中由假实体(1.0, 0.0)
标记的末端)。所以我们得到的是以下等式:
e1.t * required_width + e1.width < e2.t * required_width
或者如果你解决了它required_width
你会得到
e1.width / (e2.t - e1.t) < required_width