/// <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; } } } } }