예제 #1
0
        /// <summary>
        /// 将指定的拼图碎片与当前的拼图碎片合并。不检查两个拼图碎片是否可以被合并。
        /// </summary>
        /// <param name="piece">要合并的拼图碎片。</param>
        public void Merge(JigsawPiece piece)
        {
            // 更新相邻拼图碎片信息。
            foreach (JigsawPiece p in piece.neighbors)
            {
                p.neighbors.Remove(piece);
                p.neighbors.Add(this);
            }
            this.neighbors.UnionWith(piece.neighbors);
            this.neighbors.Remove(this);
            // 更新形状。
            float sum = this.shape.Weight + piece.shape.Weight;

            this.offset = new Vector2((this.offset.X * this.shape.Weight + piece.offset.X * piece.shape.Weight) / sum,
                                      (offset.Y * this.shape.Weight + piece.offset.Y * piece.shape.Weight) / sum);
            this.shape.Merge(piece.shape);
            // 更新路径。
            GeometryGroup newGroup = SharpDXUtility.Merge(this.originalPath, piece.originalPath);

            this.originalPath.Dispose();
            this.originalPath = newGroup;
            this.CalculateMatrix();
            this.UpdatePath();
            if (piece.PieceType == JigsawPieceType.Border)
            {
                this.pieceType = JigsawPieceType.Border;
            }
            piece.Dispose();
        }
예제 #2
0
        /// <summary>
        /// 生成拼图形状。
        /// </summary>
        public void GererateJigsawShape()
        {
            // 拼图尺寸。
            float width  = Size.Width;
            float height = Size.Height;
            // 拼图碎片的尺寸。
            float pWidth  = width / horizontalDimension;
            float pHeight = height / verticalDimension;
            // 拼图碎片的随机化尺寸。
            float rWidth = pWidth * randomization / 3;
            float rHeight = pHeight * randomization / 3;
            float x, y;

            // 最后一行节点。
            Vector2[] corners   = new Vector2[horizontalDimension + 1];
            Vector2   lastPoint = new Vector2();

            // 最后一行的边凹凸性。
            bool[] borders    = new bool[horizontalDimension + 1];
            bool   lastBorder = false;

            // 最后一行的随机数。
            float[][] values    = new float[horizontalDimension + 1][];
            float[]   lastValue = null;
            for (int i = 0; i <= this.verticalDimension; i++)
            {
                for (int j = 0; j <= this.horizontalDimension; j++)
                {
                    y = pHeight * i;
                    if (i > 0 && i < this.verticalDimension && rHeight != 0f)
                    {
                        y += (float)((RandomExt.NextDouble() * 2 - 1) * rHeight);
                    }
                    x = pWidth * j;
                    if (j > 0 && j < horizontalDimension && rWidth != 0f)
                    {
                        x += (float)((RandomExt.NextDouble() * 2 - 1) * rWidth);
                    }
                    Vector2 currentPoint = new Vector2(x, y);
                    if (i == 0)
                    {
                        corners[j] = currentPoint;
                    }
                    else if (j == 0)
                    {
                        lastPoint = currentPoint;
                    }
                    else
                    {
                        // 将拼图碎片放置在国际象棋盘上,每片会分别对应黑色和白色。
                        bool isBlack = (i + j) % 2 == 0;
                        Path path    = new Path(corners[j], isBlack);
                        // 逆时针添加边。
                        // 顶边。
                        if (i == 1)
                        {
                            path.AddLine(corners[j - 1]);
                        }
                        else
                        {
                            AddBorder(path, corners[j], corners[j - 1], !borders[j], values[j]);
                        }
                        // 左边。
                        if (j == 1)
                        {
                            path.AddLine(lastPoint);
                        }
                        else
                        {
                            AddBorder(path, corners[j - 1], lastPoint, !lastBorder, lastValue);
                        }
                        // 底边。
                        if (i == verticalDimension)
                        {
                            path.AddLine(currentPoint);
                        }
                        else
                        {
                            borders[j] = RandomExt.NextBoolean();
                            values[j]  = GenerateRandom();
                            AddBorder(path, lastPoint, currentPoint, borders[j], values[j]);
                        }
                        // 右边。
                        if (j == horizontalDimension)
                        {
                            path.AddLine(corners[j]);
                        }
                        else
                        {
                            lastBorder = RandomExt.NextBoolean();
                            lastValue  = GenerateRandom();
                            AddBorder(path, currentPoint, corners[j], lastBorder, lastValue);
                        }
                        this.paths.Add(path);
                        // 计算形状的重心。
                        Vector2 c1 = SharpDXUtility.GetCenter(corners[j - 1], corners[j], lastPoint);
                        Vector2 c2 = SharpDXUtility.GetCenter(corners[j], lastPoint, currentPoint);
                        float   w1 = SharpDXUtility.Area(corners[j - 1], corners[j], lastPoint);
                        float   w2 = SharpDXUtility.Area(corners[j], lastPoint, currentPoint);
                        path.Weight    = w1 + w2;
                        path.Center    = new Vector2((c1.X * w1 + c2.X * w2) / path.Weight, (c1.Y * w1 + c2.Y * w2) / path.Weight);
                        corners[j - 1] = lastPoint;
                        lastPoint      = currentPoint;
                        if (j == this.horizontalDimension)
                        {
                            corners[j] = currentPoint;
                        }
                    }
                }
            }
        }