1: /*
2: Copyright (c) 2010 <a href="http://www.gutgames.com">James Craig</a>
3:
4: Permission is hereby granted, free of charge, to any person obtaining a copy
5: of this software and associated documentation files (the "Software"), to deal
6: in the Software without restriction, including without limitation the rights
7: to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8: copies of the Software, and to permit persons to whom the Software is
9: furnished to do so, subject to the following conditions:
10:
11: The above copyright notice and this permission notice shall be included in
12: all copies or substantial portions of the Software.
13:
14: THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15: IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16: FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17: AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18: LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19: OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20: THE SOFTWARE.*/
21:
22: #region Usings
23: using System;
24: using System.Collections.Generic;
25: using System.Linq;
26: using System.Text;
27: using System.Drawing;
28: using System.Drawing.Imaging;
29: #endregion
30:
31: namespace Utilities.Media.Image
32: {
33: /// <summary>
34: /// Helper class for generating cracks by midpoint displacement
35: /// </summary>
36: public static class MidpointDisplacement
37: {
38: #region Functions
39:
40: /// <summary>
41: /// Generates an image that contains cracks
42: /// </summary>
43: /// <param name="Width">Image width</param>
44: /// <param name="Height">Image height</param>
45: /// <param name="NumberOfCracks">Number of cracks</param>
46: /// <param name="Iterations">Iterations</param>
47: /// <param name="MaxChange">Maximum height change of the cracks</param>
48: /// <param name="MaxLength">Maximum length of the cracks</param>
49: /// <param name="Seed">Random seed</param>
50: /// <returns>An image containing "cracks"</returns>
51: public static Bitmap Generate(int Width,int Height,int NumberOfCracks,int Iterations,
52: int MaxChange,int MaxLength,int Seed)
53: {
54: Bitmap ReturnValue = new Bitmap(Width, Height);
55: List<Line> Lines = GenerateLines(Width,Height,NumberOfCracks, Iterations, MaxChange, MaxLength, Seed);
56: using (Graphics ReturnGraphic = Graphics.FromImage(ReturnValue))
57: {
58: foreach (Line Line in Lines)
59: {
60: foreach (Line SubLine in Line.SubLines)
61: {
62: ReturnGraphic.DrawLine(Pens.White, SubLine.X1, SubLine.Y1, SubLine.X2, SubLine.Y2);
63: }
64: }
65: }
66: return ReturnValue;
67: }
68:
69: private static List<Line> GenerateLines(int Width,int Height,int NumberOfCracks, int Iterations, int MaxChange, int MaxLength, int Seed)
70: {
71: List<Line> Lines = new List<Line>();
72: System.Random Generator = new System.Random(Seed);
73: for (int x = 0; x < NumberOfCracks; ++x)
74: {
75: Line TempLine = null;
76: int LineLength = 0;
77: do
78: {
79: TempLine = new Line(Generator.Next(0, Width), Generator.Next(0, Width),
80: Generator.Next(0, Height), Generator.Next(0, Height));
81: LineLength = (int)System.Math.Sqrt((double)((TempLine.X1 - TempLine.X2) * (TempLine.X1 - TempLine.X2))
82: + ((TempLine.Y1 - TempLine.Y2) * (TempLine.Y1 - TempLine.Y2)));
83: } while (LineLength > MaxLength&&LineLength<=0);
84: Lines.Add(TempLine);
85: List<Line> TempLineList = new List<Line>();
86: TempLineList.Add(TempLine);
87: for (int y = 0; y < Iterations; ++y)
88: {
89: Line LineUsing=TempLineList[Generator.Next(0,TempLineList.Count)];
90: int XBreak=Generator.Next(LineUsing.X1,LineUsing.X2)+Generator.Next(-MaxChange,MaxChange);
91: int YBreak = 0;
92: if (LineUsing.Y1 > LineUsing.Y2)
93: {
94: YBreak = Generator.Next(LineUsing.Y2, LineUsing.Y1) + Generator.Next(-MaxChange, MaxChange);
95: }
96: else
97: {
98: YBreak = Generator.Next(LineUsing.Y1, LineUsing.Y2) + Generator.Next(-MaxChange, MaxChange);
99: }
100: Line LineA=new Line(LineUsing.X1,XBreak,LineUsing.Y1,YBreak);
101: Line LineB=new Line(XBreak,LineUsing.X2,YBreak,LineUsing.Y2);
102: TempLineList.Remove(LineUsing);
103: TempLineList.Add(LineA);
104: TempLineList.Add(LineB);
105: }
106: TempLine.SubLines=TempLineList;
107: }
108: return Lines;
109: }
110:
111: #endregion
112: }
113:
114: #region Internal classes
115:
116: internal class Line
117: {
118: public Line(){}
119:
120: public Line(int X1,int X2,int Y1,int Y2)
121: {
122: if (X1 > X2)
123: {
124: int Holder = X1;
125: X1 = X2;
126: X2 = Holder;
127: Holder = Y1;
128: Y1 = Y2;
129: Y2 = Holder;
130: }
131: this.X1=X1;
132: this.X2=X2;
133: this.Y1=Y1;
134: this.Y2=Y2;
135: }
136:
137: public int X1;
138: public int X2;
139: public int Y1;
140: public int Y2;
141: public List<Line> SubLines = new List<Line>();
142: }
143:
144: #endregion
145: }