ジグソーの複数分割
ピースの生成はできましたが、最終的には一枚絵からジグソーを作成するため
分割数を指定して、それに応じたピースを生成するようにしていきます
ジグソーの境界
隣り合うジグソーの境界は同じものを使う必要がありますが
すべてのピースを時計回りで境界を作成すると境界の向きが変わってしまい
上手に作成することができなくなります
時計回りで作成した場合、
1つ目を「(0, 0) -> (0, 1) -> (1, 1) -> (1, 0)」とすると
2つ目は「(1, 0) -> (1, 1) -> (2, 1) -> (2, 0)」となる
境界部分は、1つ目は(1, 1) -> (1, 0) なのに対し 2つ目は(1, 0) -> (1, 1) となり
向きが合わない
そのためピースの位置によってピースの作成する向きを下図のように変更する必要がある
コード
ピース毎の外周取得の処理は以下のようになる
// 反時計回り private static readonly Vector2Int[] clockwisePosition = { Vector2Int.zero, Vector2Int.right, Vector2Int.one, Vector2Int.up }; // 時計回り private static readonly Vector2Int[] counterclockwisePosition = { Vector2Int.zero, Vector2Int.up, Vector2Int.one, Vector2Int.right }; private static List<BezierPathSegment> GetPieceSegment(JigsawParam param, int x, int y, ref List<Border> borders) { var ret = new List<BezierPathSegment>(); var isClockwise = (x + y) % 2 == 0; foreach (var position in isClockwise ? clockwisePosition : counterclockwisePosition) { var begin = new Vector2Int(x + position.x, y + position.y); var end = isClockwise ? new Vector2Int(position.y == 0 ? x + 1 : x, y + position.x) : new Vector2Int(x + position.y, position.x == 0 ? y + 1 : y); // 端のピース if ( begin.x == 0 && end.x == 0 || begin.y == 0 && end.y == 0 || begin.x == param.Horizontal && end.x == param.Horizontal || begin.y == param.Vertical && end.y == param.Vertical ) { ret.Add(new BezierPathSegment { P0 = new Vector2(begin.x, begin.y), P1 = new Vector2(end.x, end.y), P2 = new Vector2(begin.x, begin.y), }); continue; } var border = borders.Find(b => b.Begin == begin && b.End == end); if (border == null) { border = new Border(begin, end, GetBorder(begin, end)); borders.Add(border); } ret.AddRange(border.Segments); } return ret; }
ジグソー生成
これにより分割数を指定すると自動でジグソーが生成されるようになった