创建一个益智游戏,我想根据用户输入变形形状。用户单击顶点并拖动更改形状的点。例如,如果用户点击A并向下拖动(缩短段AG),则点B将下降等量(缩短BC),点F将向左移动缩短AF和FG,最后点E也将转移到左边与F点保持一致。
有一系列线段,每个线段本身就是一个包含两个端点的数组。换班时我有一个循环搜索所有相等的点。所有这些都不是为了让这一切发挥作用而愿意做出任何改变。
我已经为此工作了两天而且完全难过了。
A
B-------------\
| | \
| | \
| | \
| | \
C------------------\F
| G |
| |
| |
D-------------------E
答案 0 :(得分:3)
同时方程,不是吗?
我假设每条线都应保持其斜率。然后你的数字满足这些方程(或几乎这些方程,我不是100%确定自动对焦线的斜率):
B.x = C.x = D.x
B.y = A.y
C.y = G.y = F.y
D.y = E.y
A.x = G.x
F.x = E.x
(A.y - F.y)= 2(F.x - A.x)
当玩家拖动A时,A.y和A.x实际上是恒定的,所以你有11个方程和12个未知数。 (正如Beta指出的那样,有一些欠约束,因为三个等式B.x = C.x = D.x与其他任何一个都没有关系,而D.y = E.y也没有。)
您可能想要的是改变变量最少的解决方案。我不知道该怎么做。但由于这是一款游戏,如果偶尔你没有完全最小的变化集,那也许并不重要。所以也许一个贪婪的算法会起作用,如下:
答案 1 :(得分:0)
我的第一个想法是使用单纯形算法的线性编程,但我认为这是错误的或至少是不完整的。基本上,大多数(如果不是全部)规则都是线性的 - 等于 - 规则,其中线性规划处理的是这个(或者<=或者其他)规则。
修复可能是统一的。也就是说,表达你的规则WRT尽可能少的变量。如果你有一个规则f(a)= g(b),你可以通过定义b = g'(f(a))来有效地消除b,并且在其他地方替换你找到b。由于实际替换效率低下,您只需记下a和b之间的关系即可。
轻微的并发症,基本方法是联合发现。在完全相等的情况下,您可以通过添加从b到a的链接来消除b。当'发现'b时,你会识别一个(或者它已被链接到的任何东西)。因此,您可以随时将任何规则有效地转换为仅使用非消除变量的表单。在这种情况下的复杂性 - 当你按照链接时,你需要保持g'(f(a))样式的运行轨迹。因为这是线性的,它不应该是一个大问题,但也不是微不足道的。
您可能需要能够回溯统一 - 记下您在堆栈上设置的链接,以便在展开堆栈时以正确的顺序再次将它们置零。
我不确定你是否有任何相对条件(小于或等于),但如果是这样,一旦你消除了尽可能多的变量,你仍然需要一些线性编程。如果剩下两个变量,这在概念上很简单。对于这两个变量的每个线性条件,在2D图上绘制一条线,使得线的一侧表示有效区域。条件传统上是“标准化的”,因此有效方总是包括原点。基于交叉点,最靠近原点的线段形成凸多边形。最佳解决方案是在其中一个角落,并使用线性评分规则(您正在优化的事物)进行评估,在您的情况下,该规则将被定义为给出“最佳”形状,其中存在一些模糊性或某些优先级冲突你的规则 - 例如你不能一直在一条线上推动一个点,所以事情会在某些点被阻挡。
如果剩下两个以上的变量,则需要多维等效的凸多边形 - 这称为单形。单纯形算法的实际实现涉及矩阵。
这已经过于简单,以至于它在一些细节上可能是错误的,而且就我所能解释而言。 IIRC您可以在Sedgewick中获得有关这些组件技术的详细描述,尽管维基百科最近可能同样出色。
Simplex求解器有时用于Window布局 - 例如,我认为wxWidgets使用一个来调整窗口中控件的大小。统一是逻辑编程(Prolog等)的一个定义特征,但潜在的联合查找原则很简单。关键的诀窍是弄清楚如何将2D图形转换为表达它将如何变化的一组规则,并理解如何表示和操纵这些规则,特别是以矩阵形式。
答案 2 :(得分:0)
这个怎么样...你的拼图只有三角形,矩形和正方形?在这种情况下,您可以开发一种方法来处理每个形状,具体取决于移动哪个顶点以及哪个形状受到该顶点移动的影响...在您的示例中,移动顶点A将影响方形ABCG和三角形AGF。因此,当A移动时,顶点C保持不受影响......你只需要“重新定位”B和G.除非我理解你的例子错了,否则我看不出移动A会影响F。 HTH。