根据给定的计算缺失的框尺寸
Compute missing box dimensions from given ones
给定结构:
structure box_dimensions:
int? left
int? right
int? top
int? bottom
point? top_left
point? top_right
point? bottom_left
point? bottom_right
point? top_center
point? bottom_center
point? center_left
point? center_right
point? center
int? width
int? height
rectangle? bounds
可以定义或不定义每个字段。
您将如何实现功能 check_and_complete(box_dimensions)
?
- 如果没有定义足够的字段来描述一个框,或者太多,该函数应该 return 出错。
- 如果输入一致,它应该计算未定义的字段。
您可以用中心、宽度和高度,或 top_left 和 bottom_right 个角等来描述一个盒子
我能想到的唯一解决方案包含许多 if-elses 的方法。我相信有一个聪明的方法可以做到这一点。
编辑
如果您想知道我是如何得到这样的结构的,原因如下:
我正在考虑 "layout by constraints" 系统的想法:
用户定义一堆框,并为每个框定义一组约束,如"box_a.top_left = box_b.bottom_right"、"box_a.width = box_b.width / 2"。
真正的结构字段实际上是表达式 AST,而不是值。
所以我需要检查一个框是 "underconstrained" 还是 "overconstrained",如果没问题,根据给定的创建缺少的表达式 AST。
是的,肯定会有很多if-else
。
这是我让它们合理组织的尝试:
howManyLefts = 0
if (left is set) { realLeft = left; howManyLefts++; }
if (top_left is set) { realLeft = top_left.left; howManyLefts++; }
if (bottom_left is set) { realLeft = bottom_left.left; howManyLefts++; }
if (center_left is set) { realLeft = center_left.left; howManyLefts++; }
if (bounds is set) { realLeft = bounds.left; howManyLefts++; }
if (howManyLefts > 1) return error;
现在,为 center
、right
和 width
重复该代码块。
现在你最终得到 howManyLefts
、howManyCenters
、howManyRights
和 howManyWidths
,它们都是零或一,具体取决于是否提供了值。您需要 正好 两个值设置和两个未设置,所以:
if (howManyLefts + howManyRights + howManyCenters + howManyWidths != 2) return error
if (howManyWidths == 0)
{
// howManyWidths is 0, so we look for the remaining 0 and assume the rest is 1s
if (howManyCenters == 0)
{ realWidth = realRight - realLeft; realCenter = (realRight + realLeft) / 2; }
else if (howManyLefts == 0)
{ realWidth = 2 * (realRight - realCenter); realLeft = realRight - realWidth; }
else
{ realWidth = 2 * (realCenter - realLeft); realRight = realLeft + realWidth; }
}
else
{
// howManyWidths is 1, so we look for the remaining 1 and assume the rest is 0s
if (howManyCenters == 1)
{ realLeft = realCenter - realWidth / 2; realRight = realCenter + realWidth / 2; }
else if (howManyLefts == 1)
{ realRight = realLeft + realWidth; realCenter = (realRight + realLeft) / 2; }
else
{ realLeft = realRight - realWidth; realCenter = (realRight + realLeft) / 2; }
}
现在,重复垂直轴的所有内容(即将 { left
、center
、right
、width
} 替换为 { top
、center
, bottom
, height
}).
给定结构:
structure box_dimensions:
int? left
int? right
int? top
int? bottom
point? top_left
point? top_right
point? bottom_left
point? bottom_right
point? top_center
point? bottom_center
point? center_left
point? center_right
point? center
int? width
int? height
rectangle? bounds
可以定义或不定义每个字段。
您将如何实现功能 check_and_complete(box_dimensions)
?
- 如果没有定义足够的字段来描述一个框,或者太多,该函数应该 return 出错。
- 如果输入一致,它应该计算未定义的字段。
您可以用中心、宽度和高度,或 top_left 和 bottom_right 个角等来描述一个盒子
我能想到的唯一解决方案包含许多 if-elses 的方法。我相信有一个聪明的方法可以做到这一点。
编辑
如果您想知道我是如何得到这样的结构的,原因如下:
我正在考虑 "layout by constraints" 系统的想法:
用户定义一堆框,并为每个框定义一组约束,如"box_a.top_left = box_b.bottom_right"、"box_a.width = box_b.width / 2"。
真正的结构字段实际上是表达式 AST,而不是值。
所以我需要检查一个框是 "underconstrained" 还是 "overconstrained",如果没问题,根据给定的创建缺少的表达式 AST。
是的,肯定会有很多if-else
。
这是我让它们合理组织的尝试:
howManyLefts = 0
if (left is set) { realLeft = left; howManyLefts++; }
if (top_left is set) { realLeft = top_left.left; howManyLefts++; }
if (bottom_left is set) { realLeft = bottom_left.left; howManyLefts++; }
if (center_left is set) { realLeft = center_left.left; howManyLefts++; }
if (bounds is set) { realLeft = bounds.left; howManyLefts++; }
if (howManyLefts > 1) return error;
现在,为 center
、right
和 width
重复该代码块。
现在你最终得到 howManyLefts
、howManyCenters
、howManyRights
和 howManyWidths
,它们都是零或一,具体取决于是否提供了值。您需要 正好 两个值设置和两个未设置,所以:
if (howManyLefts + howManyRights + howManyCenters + howManyWidths != 2) return error
if (howManyWidths == 0)
{
// howManyWidths is 0, so we look for the remaining 0 and assume the rest is 1s
if (howManyCenters == 0)
{ realWidth = realRight - realLeft; realCenter = (realRight + realLeft) / 2; }
else if (howManyLefts == 0)
{ realWidth = 2 * (realRight - realCenter); realLeft = realRight - realWidth; }
else
{ realWidth = 2 * (realCenter - realLeft); realRight = realLeft + realWidth; }
}
else
{
// howManyWidths is 1, so we look for the remaining 1 and assume the rest is 0s
if (howManyCenters == 1)
{ realLeft = realCenter - realWidth / 2; realRight = realCenter + realWidth / 2; }
else if (howManyLefts == 1)
{ realRight = realLeft + realWidth; realCenter = (realRight + realLeft) / 2; }
else
{ realLeft = realRight - realWidth; realCenter = (realRight + realLeft) / 2; }
}
现在,重复垂直轴的所有内容(即将 { left
、center
、right
、width
} 替换为 { top
、center
, bottom
, height
}).