按:笔者此时已经完成了一个不完美的版本,已经把笔者的真实的七巧板解法算到了216 个,应该是不重复的。至于是不是还有更多的解法,目前不知道。因为我的算法的某些情况没有处理,因此不是一个完美的做法。本着循序渐进的宗旨,介绍一下笔者使用的自定义的类。
多边形的传统表示使用点集,至少三个点。为了便于多边形的各种计算,笔者采用了一种具有方向的结构来表示,即链表结构。请参考如下代码:
public class TangramPolygon
{
public readonly Vertex[] m_VertexArr;// The set of all the vertex of the polygon
public readonly PointF[] m_OrgPointArr;// The set of all the vertex of the polygon
public int firstPntIdx;// used to recored the first point of the polygon which is is dynamic one
public bool bArrayOrgOrder = true;// the the oder of the array elements , true: the original oder, false after fliped.
public bool bFliped = false;// if the polygon has been fliped.
public int usingIdx;// the index that is being used to match the box, based from 0
public TangramPolygon usingBoxPlg;// the box polygon is being used.
public TangramPolygon mountedPlg;// the part polygon is being fixed or set, used to draw the last diagrame.
private Dictionary<int, TangramPolygon> m_AllStatesPlg ; // record all of the rotated and flipped unique from of this parent polygon
private int m_StatePlgIndex;// the index of the state polygon being used
....
}
其中用到的 Vertex 定义如下:
public class Vertex
{
public Vertex()
{
m_Point = new PointF();
}
public PointF m_Point;
public int idx;
public int last_idx;
public int next_idx;
}
根据Vertex的定义,就可以建立一个链表结构。
这个结构就是一个普通形式的链表结构,下面把 TangramPolygon 中的几个关键成员变量介绍一下
m_OrgPointArr 原始点的数组,所谓原始点就是没有经过计算的原始数据点。在计算过程当中,除非指定,不参与旋转平移等坐标变换。
firstPntIdx: 目前定义是值得多边形的top-left点(屏幕坐标系)对应的点的下标编号,即索引值。在初始状态下,一般都是0. 但是经过旋转之后,可能会发生变化。
bArrayOrgOrder : 指的是m_VertexArr 中的点的顺序是否可初始状态一致,一致则为true。 初始状态的点的顺序是逆时针方向的。
bFliped : 这个多边形是否经过翻转运算。
usingIdx:指得是点或边的索引,这个索引标明在进行多边形匹配时的启示匹配边的索引。
usingBoxPlg:如果这个部件多边形已经放入了盒子中,该值记录的是放入时盒子空余部分的多边形。
如图示:
红色区域是F部件要放入的区域(包括F那个区域, 即下图中的红色区域),这个区域就是usingBoxPlg。 它用于重复摆放,便于回溯。
mountedPlg: 即安装好的多边形,即上图中的F。用于记录中间过程,回放时会使用。
m_AllStatesPlg : 这是几个本多边形进行旋转和反转后的多边形字典,目的是提前做好准备,这样在具体摆放时不用在进行旋转和反转计算。事实证明,这样做将速度提高近100倍。
说明:本人采用的算法要按照一定的顺序,从某条边开始匹配盒子多边形;很显然,有的多边形的第一边和其余变边在反转和旋转后并没有任何区别,例如一个正方形,因此正好行的贴合匹配计算只要看一条边就够了。根据这种思想,可以事先计算好旋转和翻转后的多边形,然后记录本变量中。这种多边形,我命名为stateboxplg
m_StatePlgIndex: 上述多边形在m_AllStatesPlg 中索引(键值)
这个类里面还有很多函数,暂不介绍。
今天是51, 北京为了清零,为了为了什么,所有餐饮业暂停营业。
maraSun 于 BJFWDQ
2022-05-01
祝大家五一快乐!