Start with a single horizontal line segment.
Repeat for a sufficiently large number of times
{
Repeat over each line segment in the scene
{
Find the midpoint of the line segment.
Displace the midpoint in Y by a random amount.
Reduce the range for random numbers.
}
}
void Generate1DMountain(Vector3 start, Vector3 end, int iterateTime, float roughless)
{
if (iterateTime > 0)
{
float rand = Random.Range(0f, 2.999f) * roughless;
Vector3 mid = new Vector3(0.5f * start.x + 0.5f * end.x, 0.5f * start.y + 0.5f * end.y + rand, 0);
--iterateTime;
Generate1DMountain(start, mid, iterateTime, roughless * iterateTime * iterateTime * 0.01f);
points.Add(mid);
Generate1DMountain(mid, end, iterateTime, roughless * iterateTime * iterateTime * 0.01f);
}
}
float GetMidHeight(int i, int stride, Vector3[] points)
{
return 0.5f * (points[i - stride].y + points[i + stride].y);
}
Vector3[] Generater1DMoutainIterative(Vector3 start, Vector3 end, int iterateTime, float heightScale, float h)
{
int length = CalculateArrayLenght(iterateTime);
Vector3[] points = new Vector3[length];
points[0] = start;
points[length - 1] = end;
float gap = Mathf.Abs(end.x - start.x) / length;
//Debug.Log("gap: " + gap);
for(int i=0; i< length; i++)
{
points[i] = new Vector3(start.x + i*gap, 0f, 0f);
}
float ratio, scale;
ratio = (float)Mathf.Pow(2.0f, -h);
scale = heightScale * ratio;
int stride = length / 2;
while(stride != 0)
{
for (int i = stride; i < length; i += stride)
{
points[i].y = scale * Random.Range(-4f, 4f) + GetMidHeight(i, stride, points);
i += stride;
}
scale *= ratio;
Debug.Log("Stride: " + stride);
stride >>= 1;
}
// DumpAllPoint(points);
return points;
}
void OnDrawGizmos()
{
Gizmos.color = Color.red;
for (int i = 0; i < newPoints.Length - 1; i++)
{
Gizmos.DrawLine(newPoints[i], newPoints[i + 1]);
}
}
结果
public class EdgeMidHashTable
{
List edges;
List midNodes;
public EdgeMidHashTable()
{
edges = new List();
midNodes = new List();
}
public void Clear()
{
edges.Clear();
midNodes.Clear();
}
public void Add(Edge edge, Node node)
{
edges.Add(edge);
midNodes.Add(node);
}
public bool IsContainsEdge(Edge edge)
{
return edges.Contains(edge);
}
public Node GetEdgeMidNode(Edge edge)
{
int index = GetEdgeIndex(edge);
return midNodes[index];
}
int GetEdgeIndex(Edge edge)
{
for(int i = 0; i< edges.Count; i++)
{
if(edges[i].Equals(edge))
{
return i;
}
}
return -1;
}
}
public class Edge
{
int startNodeIndex;
int endNodeIndex;
public EdgeLabel label;
public Node StartNode;
public Node EndNode;
public Edge()
{ }
public Edge(Node Start, Node End)
{
label = EdgeLabel.Neutral;
startNodeIndex = Start.vertexIndex;
StartNode = Start;
endNodeIndex = End.vertexIndex;
EndNode = End;
}
public override bool Equals(object other)
{
if(other == null)
{
return false;
}
Edge otherEdge = (Edge)other;
if ((StartNode.vertexIndex == otherEdge.StartNode.vertexIndex && EndNode.vertexIndex == otherEdge.EndNode.vertexIndex) ||
(StartNode.vertexIndex == otherEdge.EndNode.vertexIndex && EndNode.vertexIndex == otherEdge.StartNode.vertexIndex))
{
return true;
}
return false;
}
public Edge(Node Start, Node End, EdgeLabel _label)
{
label = _label;
startNodeIndex = Start.vertexIndex;
StartNode = Start;
endNodeIndex = End.vertexIndex;
EndNode = End;
}
public Vector3 GetEdgeCenter()
{
return (StartNode.position + EndNode.position) * 0.5f;
}
public override int GetHashCode()
{
return this.label.GetHashCode();
}
}
public class Node
{
public Vector3 position;
public int vertexIndex = -1;
public Node(Vector3 _pos)
{
position = _pos;
}
public override bool Equals(object other)
{
if (other == null)
{
return false;
}
Node otherNode = (Node)other;
if (this.vertexIndex == otherNode.vertexIndex)
{
return true;
}
return false;
}
}
public class Triange
{
public Node[] vertices = new Node[3];
public Triange(Vector3 Vertex0, Vector3 Vertex1, Vector3 Vertex2)
{
vertices[0] = new Node(Vertex0);
vertices[1] = new Node(Vertex1);
vertices[2] = new Node(Vertex2);
}
public Triange(Node node0, Node node1, Node node2)
{
vertices[0] = node0;
vertices[1] = node1;
vertices[2] = node2;
}
}
void SplitTriangle(Triange triangle, int recursiveTime)
{
Vector3 VertexPos0 = triangle.vertices[0].position;
Vector3 VertexPos1 = triangle.vertices[1].position;
Vector3 VertexPos2 = triangle.vertices[2].position;
float RandomScale = Vector3.Distance(VertexPos0, VertexPos1);
float rand0 = 0f;
float rand1 = 0f;
float rand2 = 0f;
Node midNode0 = new Node(Vector3.zero);
Node midNode1 = new Node(Vector3.zero);
Node midNode2 = new Node(Vector3.zero);
midNode0 = CalculateMidNode(RandomScale, triangle.vertices[0], triangle.vertices[1]);
midNode1 = CalculateMidNode(RandomScale, triangle.vertices[1], triangle.vertices[2]);
midNode2 = CalculateMidNode(RandomScale, triangle.vertices[0], triangle.vertices[2]);
Triange triangle0 = new Triange(triangle.vertices[0], midNode0, midNode2);
Triange triangle1 = new Triange(midNode0, triangle.vertices[1], midNode1);
Triange triangle2 = new Triange(midNode2, midNode1, triangle.vertices[2]);
Triange triangle3 = new Triange(midNode0, midNode1, midNode2);
if(recursiveTime >0)
{
recursiveTime--;
SplitTriangle2(triangle0, recursiveTime);
SplitTriangle2(triangle1, recursiveTime);
SplitTriangle2(triangle2, recursiveTime);
SplitTriangle2(triangle3, recursiveTime);
}
else if(recursiveTime == 0)
{
FinalTriangleList.Add(triangle0);
FinalTriangleList.Add(triangle1);
FinalTriangleList.Add(triangle2);
FinalTriangleList.Add(triangle3);
}
}
public void GenerateMesh()
{
meshVertices = new List();
meshTriangles = new List();
for (int i = 0; i < nodes.Count; i++)
{
meshVertices.Add(nodes[i].position);
}
for (int i = 0; i < FinalTriangleList.Count; i++)
{
meshTriangles.Add(FinalTriangleList[i].vertices[0].vertexIndex);
meshTriangles.Add(FinalTriangleList[i].vertices[1].vertexIndex);
meshTriangles.Add(FinalTriangleList[i].vertices[2].vertexIndex);
}
Mesh mesh = new Mesh();
GetComponent().mesh = mesh;
mesh.vertices = meshVertices.ToArray();
mesh.triangles = meshTriangles.ToArray();
mesh.RecalculateNormals();
}
public class SquigTriangle
{
public Edge[] edges = new Edge[3];
public SquigTriangle()
{
}
public SquigTriangle(Edge edge0, Edge edge1, Edge edge2)
{
edges[0] = edge0;
edges[1] = edge1;
edges[2] = edge2;
}
public SquigTriangle(Node node0, Node node1, Node node2)
{
edges[0] = new Edge(node0, node1);
edges[1] = new Edge(node1, node2);
edges[2] = new Edge(node2, node0);
}
///
/// Construct by nodes and labels.label0 ->Edge(node0, node1); label1 -> Edge(node1, node2); label2 -> Edge(node2, node0)
///
public SquigTriangle(Node node0, Node node1, Node node2, EdgeLabel label0, EdgeLabel label1, EdgeLabel label2)
{
edges[0] = new Edge(node0, node1, label0);
edges[1] = new Edge(node1, node2, label1);
edges[2] = new Edge(node2, node0, label2);
}
public int GetEnteryEdgeIndex()
{
for(int i = 0; i< 3; i++)
{
if(edges[i].label == EdgeLabel.Entry)
{
return i;
}
}
return -1;
}
public int GetExitEdgeIndex()
{
for(int i = 0; i< 3; i++)
{
if (edges[i].label == EdgeLabel.Exit)
{
return i;
}
}
return -1;
}
public bool IsNeutralTriangle()
{
return edges[0].label == EdgeLabel.Neutral && edges[1].label == EdgeLabel.Neutral;
}
///
/// Sort Triangle's vertices.
///
public void Resort()
{
if (edges[0].label == EdgeLabel.Neutral && edges[1].label == EdgeLabel.Neutral)
{
return;
}
Node[] nodes = new Node[4];
for(int i = 0; i< 3; i++)
{
if(edges[i].label == EdgeLabel.Entry)
{
nodes[0] = edges[i].StartNode;
nodes[1] = edges[i].EndNode;
}
if (edges[i].label == EdgeLabel.Exit)
{
nodes[2] = edges[i].StartNode;
nodes[3] = edges[i].EndNode;
}
}
if (nodes[0].vertexIndex == nodes[2].vertexIndex )
{
//0->1->3
edges[0]= new Edge(nodes[0], nodes[1] , EdgeLabel.Entry);
edges[1] = new Edge(nodes[1], nodes[3], EdgeLabel.Neutral);
edges[2] = new Edge(nodes[3], nodes[0], EdgeLabel.Exit);
}
else if(nodes[0].vertexIndex == nodes[3].vertexIndex)
{
//0->1->2
edges[0] = new Edge(nodes[0], nodes[1], EdgeLabel.Entry);
edges[1] = new Edge(nodes[1], nodes[2], EdgeLabel.Neutral);
edges[2] = new Edge(nodes[2], nodes[0], EdgeLabel.Exit);
}
else if(nodes[1].vertexIndex == nodes[2].vertexIndex)
{
//1->0->3
edges[0] = new Edge(nodes[1], nodes[0], EdgeLabel.Entry);
edges[1] = new Edge(nodes[0], nodes[3], EdgeLabel.Neutral);
edges[2] = new Edge(nodes[3], nodes[1], EdgeLabel.Exit);
}
if(nodes[1].vertexIndex == nodes[3].vertexIndex)
{
//1->0->2
edges[0] = new Edge(nodes[1], nodes[0], EdgeLabel.Entry);
edges[1] = new Edge(nodes[0], nodes[2], EdgeLabel.Neutral);
edges[2] = new Edge(nodes[2], nodes[1], EdgeLabel.Exit);
}
}
}
// / \
// /__0_\
// / \3 / \
// /_1_\/_2_\
SquigTriangle[] SubdivideSquigTriange(SquigTriangle triangle)
{
//When Come up with Neutral triangle(with three Neutral edge)
if (triangle.edges[0].label == EdgeLabel.Neutral && triangle.edges[1].label == EdgeLabel.Neutral)
{
FinalTriangleList.Add(triangle);
return new SquigTriangle[] { };
}
Node OriginalNode0 = triangle.edges[0].StartNode;
Node OriginalNode1 = triangle.edges[0].EndNode;
Node OriginalNode2 = triangle.edges[1].EndNode;
//Splite three edges to 6 small edge.
//OriginEdge0 -> edge0 + edge3
//OriginEdge1 -> edge4 + edge7
//OriginEdge2 -> edge2 + edge8
Edge[] splitedEdges = new Edge[9];
SpliteEdge(triangle.edges[0], out splitedEdges[0], out splitedEdges[3]);
SpliteEdge(triangle.edges[1], out splitedEdges[4], out splitedEdges[7]);
SpliteEdge(triangle.edges[2], out splitedEdges[8],out splitedEdges[2]);
SquigTriangle successor0 = new SquigTriangle();
SquigTriangle successor1 = new SquigTriangle();
SquigTriangle successor2 = new SquigTriangle();
SquigTriangle successor3 = new SquigTriangle();
//Construct remain edges. Four situation. Take Symmetry into consideration
//Situation 1
if (splitedEdges[0].label == EdgeLabel.Entry && splitedEdges[2].label == EdgeLabel.Exit )
{
successor0 = new SquigTriangle(OriginalNode0, EdgeMidHashTable.GetEdgeMidNode(triangle.edges[0]), EdgeMidHashTable.GetEdgeMidNode(triangle.edges[2]),
EdgeLabel.Entry, EdgeLabel.Neutral, EdgeLabel.Exit);
successor1 = new SquigTriangle(EdgeMidHashTable.GetEdgeMidNode(triangle.edges[0]), OriginalNode1, EdgeMidHashTable.GetEdgeMidNode(triangle.edges[1]),
EdgeLabel.Neutral, EdgeLabel.Neutral, EdgeLabel.Neutral);
successor2 = new SquigTriangle(EdgeMidHashTable.GetEdgeMidNode(triangle.edges[2]), EdgeMidHashTable.GetEdgeMidNode(triangle.edges[1]), OriginalNode2,
EdgeLabel.Neutral, EdgeLabel.Neutral, EdgeLabel.Neutral);
successor3 = new SquigTriangle(EdgeMidHashTable.GetEdgeMidNode(triangle.edges[1]), EdgeMidHashTable.GetEdgeMidNode(triangle.edges[2]), EdgeMidHashTable.GetEdgeMidNode(triangle.edges[0]),
EdgeLabel.Neutral, EdgeLabel.Neutral, EdgeLabel.Neutral);
}
else if(splitedEdges[2].label == EdgeLabel.Entry && splitedEdges[0].label == EdgeLabel.Exit)
{
successor0 = new SquigTriangle(OriginalNode0, EdgeMidHashTable.GetEdgeMidNode(triangle.edges[0]), EdgeMidHashTable.GetEdgeMidNode(triangle.edges[2]),
EdgeLabel.Exit, EdgeLabel.Neutral, EdgeLabel.Entry);
successor1 = new SquigTriangle(EdgeMidHashTable.GetEdgeMidNode(triangle.edges[0]), OriginalNode1, EdgeMidHashTable.GetEdgeMidNode(triangle.edges[1]),
EdgeLabel.Neutral, EdgeLabel.Neutral, EdgeLabel.Neutral);
successor2 = new SquigTriangle(EdgeMidHashTable.GetEdgeMidNode(triangle.edges[2]), EdgeMidHashTable.GetEdgeMidNode(triangle.edges[1]), OriginalNode2,
EdgeLabel.Neutral, EdgeLabel.Neutral, EdgeLabel.Neutral);
successor3 = new SquigTriangle(EdgeMidHashTable.GetEdgeMidNode(triangle.edges[1]), EdgeMidHashTable.GetEdgeMidNode(triangle.edges[2]), EdgeMidHashTable.GetEdgeMidNode(triangle.edges[0]),
EdgeLabel.Neutral, EdgeLabel.Neutral, EdgeLabel.Neutral);
}
//Situation 2
else if (splitedEdges[0].label == EdgeLabel.Entry && splitedEdges[8].label == EdgeLabel.Exit)
{
successor0 = new SquigTriangle(OriginalNode0, EdgeMidHashTable.GetEdgeMidNode(triangle.edges[0]), EdgeMidHashTable.GetEdgeMidNode(triangle.edges[2]),
EdgeLabel.Entry, EdgeLabel.Exit, EdgeLabel.Neutral);
successor1 = new SquigTriangle(EdgeMidHashTable.GetEdgeMidNode(triangle.edges[0]), OriginalNode1, EdgeMidHashTable.GetEdgeMidNode(triangle.edges[1]),
EdgeLabel.Neutral, EdgeLabel.Neutral, EdgeLabel.Neutral);
successor2 = new SquigTriangle(EdgeMidHashTable.GetEdgeMidNode(triangle.edges[2]), EdgeMidHashTable.GetEdgeMidNode(triangle.edges[1]), OriginalNode2,
EdgeLabel.Entry, EdgeLabel.Neutral, EdgeLabel.Exit);
successor3 = new SquigTriangle(EdgeMidHashTable.GetEdgeMidNode(triangle.edges[1]), EdgeMidHashTable.GetEdgeMidNode(triangle.edges[2]), EdgeMidHashTable.GetEdgeMidNode(triangle.edges[0]),
EdgeLabel.Exit, EdgeLabel.Entry, EdgeLabel.Neutral);
}
else if(splitedEdges[0].label == EdgeLabel.Exit && splitedEdges[8].label == EdgeLabel.Entry)
{
successor0 = new SquigTriangle(OriginalNode0, EdgeMidHashTable.GetEdgeMidNode(triangle.edges[0]), EdgeMidHashTable.GetEdgeMidNode(triangle.edges[2]),
EdgeLabel.Neutral, EdgeLabel.Exit, EdgeLabel.Entry);
successor1 = new SquigTriangle(EdgeMidHashTable.GetEdgeMidNode(triangle.edges[0]), OriginalNode1, EdgeMidHashTable.GetEdgeMidNode(triangle.edges[1]),
EdgeLabel.Exit, EdgeLabel.Neutral, EdgeLabel.Entry);
successor2 = new SquigTriangle(EdgeMidHashTable.GetEdgeMidNode(triangle.edges[2]), EdgeMidHashTable.GetEdgeMidNode(triangle.edges[1]), OriginalNode2,
EdgeLabel.Neutral, EdgeLabel.Neutral, EdgeLabel.Neutral);
successor3 = new SquigTriangle(EdgeMidHashTable.GetEdgeMidNode(triangle.edges[1]), EdgeMidHashTable.GetEdgeMidNode(triangle.edges[2]), EdgeMidHashTable.GetEdgeMidNode(triangle.edges[0]),
EdgeLabel.Neutral, EdgeLabel.Entry, EdgeLabel.Exit);
}
//Situation 3
else if (splitedEdges[3].label == EdgeLabel.Entry && splitedEdges[2].label == EdgeLabel.Exit)
{
successor0 = new SquigTriangle(OriginalNode0, EdgeMidHashTable.GetEdgeMidNode(triangle.edges[0]), EdgeMidHashTable.GetEdgeMidNode(triangle.edges[2]),
EdgeLabel.Neutral, EdgeLabel.Entry, EdgeLabel.Exit);
successor1 = new SquigTriangle(EdgeMidHashTable.GetEdgeMidNode(triangle.edges[0]), OriginalNode1, EdgeMidHashTable.GetEdgeMidNode(triangle.edges[1]),
EdgeLabel.Entry, EdgeLabel.Neutral, EdgeLabel.Exit);
successor2 = new SquigTriangle(EdgeMidHashTable.GetEdgeMidNode(triangle.edges[2]), EdgeMidHashTable.GetEdgeMidNode(triangle.edges[1]), OriginalNode2,
EdgeLabel.Neutral, EdgeLabel.Neutral, EdgeLabel.Neutral);
successor3 = new SquigTriangle(EdgeMidHashTable.GetEdgeMidNode(triangle.edges[1]), EdgeMidHashTable.GetEdgeMidNode(triangle.edges[2]), EdgeMidHashTable.GetEdgeMidNode(triangle.edges[0]),
EdgeLabel.Neutral, EdgeLabel.Exit, EdgeLabel.Entry);
}else if(splitedEdges[3].label == EdgeLabel.Exit && splitedEdges[2].label == EdgeLabel.Entry)
{
successor0 = new SquigTriangle(OriginalNode0, EdgeMidHashTable.GetEdgeMidNode(triangle.edges[0]), EdgeMidHashTable.GetEdgeMidNode(triangle.edges[2]),
EdgeLabel.Exit, EdgeLabel.Entry, EdgeLabel.Neutral);
successor1 = new SquigTriangle(EdgeMidHashTable.GetEdgeMidNode(triangle.edges[0]), OriginalNode1, EdgeMidHashTable.GetEdgeMidNode(triangle.edges[1]),
EdgeLabel.Neutral, EdgeLabel.Neutral, EdgeLabel.Neutral);
successor2 = new SquigTriangle(EdgeMidHashTable.GetEdgeMidNode(triangle.edges[2]), EdgeMidHashTable.GetEdgeMidNode(triangle.edges[1]), OriginalNode2,
EdgeLabel.Exit, EdgeLabel.Neutral, EdgeLabel.Entry);
successor3 = new SquigTriangle(EdgeMidHashTable.GetEdgeMidNode(triangle.edges[1]), EdgeMidHashTable.GetEdgeMidNode(triangle.edges[2]), EdgeMidHashTable.GetEdgeMidNode(triangle.edges[0]),
EdgeLabel.Entry, EdgeLabel.Exit, EdgeLabel.Neutral);
}
//Situation 4
else if (splitedEdges[3].label == EdgeLabel.Entry && splitedEdges[8].label == EdgeLabel.Exit)
{
successor0 = new SquigTriangle(OriginalNode0, EdgeMidHashTable.GetEdgeMidNode(triangle.edges[0]), EdgeMidHashTable.GetEdgeMidNode(triangle.edges[2]),
EdgeLabel.Neutral, EdgeLabel.Neutral, EdgeLabel.Neutral);
successor1 = new SquigTriangle(EdgeMidHashTable.GetEdgeMidNode(triangle.edges[0]), OriginalNode1, EdgeMidHashTable.GetEdgeMidNode(triangle.edges[1]),
EdgeLabel.Entry, EdgeLabel.Neutral, EdgeLabel.Exit);
successor2 = new SquigTriangle(EdgeMidHashTable.GetEdgeMidNode(triangle.edges[2]), EdgeMidHashTable.GetEdgeMidNode(triangle.edges[1]), OriginalNode2,
EdgeLabel.Entry, EdgeLabel.Neutral, EdgeLabel.Exit);
successor3 = new SquigTriangle(EdgeMidHashTable.GetEdgeMidNode(triangle.edges[1]), EdgeMidHashTable.GetEdgeMidNode(triangle.edges[2]), EdgeMidHashTable.GetEdgeMidNode(triangle.edges[0]),
EdgeLabel.Exit, EdgeLabel.Neutral, EdgeLabel.Entry);
}
else if (splitedEdges[3].label == EdgeLabel.Exit && splitedEdges[8].label == EdgeLabel.Entry)
{
successor0 = new SquigTriangle(OriginalNode0, EdgeMidHashTable.GetEdgeMidNode(triangle.edges[0]), EdgeMidHashTable.GetEdgeMidNode(triangle.edges[2]),
EdgeLabel.Neutral, EdgeLabel.Neutral, EdgeLabel.Neutral);
successor1 = new SquigTriangle(EdgeMidHashTable.GetEdgeMidNode(triangle.edges[0]), OriginalNode1, EdgeMidHashTable.GetEdgeMidNode(triangle.edges[1]),
EdgeLabel.Exit, EdgeLabel.Neutral, EdgeLabel.Entry);
successor2 = new SquigTriangle(EdgeMidHashTable.GetEdgeMidNode(triangle.edges[2]), EdgeMidHashTable.GetEdgeMidNode(triangle.edges[1]), OriginalNode2,
EdgeLabel.Exit, EdgeLabel.Neutral, EdgeLabel.Entry);
successor3 = new SquigTriangle(EdgeMidHashTable.GetEdgeMidNode(triangle.edges[1]), EdgeMidHashTable.GetEdgeMidNode(triangle.edges[2]), EdgeMidHashTable.GetEdgeMidNode(triangle.edges[0]),
EdgeLabel.Entry, EdgeLabel.Neutral, EdgeLabel.Exit);
}
Node midNode0 = new Node(triangle.edges[0].GetEdgeCenter());
Node midNode1 = new Node(triangle.edges[1].GetEdgeCenter());
Node midNode2 = new Node(triangle.edges[2].GetEdgeCenter());
Edge edge0 = new Edge(OriginalNode0, midNode0);
Edge edge1 = new Edge(midNode0, midNode2);
Edge edge2 = new Edge(midNode2, OriginalNode0);
Edge edge3 = new Edge(midNode0, OriginalNode1);
Edge edge4 = new Edge(OriginalNode1, midNode1);
Edge edge5 = new Edge(midNode1, midNode0);
Edge edge6 = new Edge(midNode2, midNode1);
Edge edge7 = new Edge(midNode1, OriginalNode2);
Edge edge8 = new Edge(OriginalNode2, midNode2);
successor0.Resort();
successor1.Resort();
successor2.Resort();
successor3.Resort();
if (!successor3.IsNeutralTriangle())
{
CrossedEdge.Add(successor3.edges[successor3.GetEnteryEdgeIndex()]);
CrossedEdge.Add(successor3.edges[successor3.GetExitEdgeIndex()]);
}
return new SquigTriangle[] { successor0, successor1, successor2, successor3 };
}
void SpliteEdge(Edge originalEdge, float roughness, out Edge subEdge0, out Edge subEdge1)
{
//float RandomScale = Vector3.Distance(originalEdge.StartNode.position, originalEdge.EndNode.position);
float randomResult = roughness * Random.Range(-0.5f, 0.5f);
float randomLowerBound = roughness * -0.5f;
float altn = 0.0f;
for (int i = 0; i < LowerRandomLimits.Count; i++)
{
altn += LowerRandomLimits[i];
}
Node midNode = new Node(Vector3.zero);
subEdge0 = new Edge();
subEdge1 = new Edge();
if (EdgeMidHashTable.IsContainsEdge(originalEdge))
{
midNode = EdgeMidHashTable.GetEdgeMidNode(originalEdge);
}else
{
switch (originalEdge.label)
{
//Entry-> Entry + Neutral
case EdgeLabel.Entry:
case EdgeLabel.Exit:
midNode = new Node(0.5f * new Vector3(originalEdge.StartNode.position.x + originalEdge.EndNode.position.x,
originalEdge.StartNode.position.y + originalEdge.EndNode.position.y, altn + randomLowerBound));
EdgeMidHashTable.Add(originalEdge, midNode);
PushNode(midNode);
break;
case EdgeLabel.Neutral:
midNode = new Node(0.5f * new Vector3(originalEdge.StartNode.position.x + originalEdge.EndNode.position.x,
originalEdge.StartNode.position.y + originalEdge.EndNode.position.y,
originalEdge.StartNode.position.z + originalEdge.EndNode.position.z /*+ altn*/ + randomResult));
EdgeMidHashTable.Add(originalEdge, midNode);
PushNode(midNode);
break;
}
}
switch (originalEdge.label)
{
//Entry-> Entry + Neutral
case EdgeLabel.Entry:
//RiverCrossed from last triangle
if (CrossedEdge.Contains(new Edge(originalEdge.StartNode, midNode)))
{
subEdge0 = new Edge(originalEdge.StartNode, midNode, EdgeLabel.Entry);
subEdge1 = new Edge(midNode, originalEdge.EndNode, EdgeLabel.Neutral);
}
else if (CrossedEdge.Contains(new Edge(midNode, originalEdge.EndNode)))
{
subEdge0 = new Edge(originalEdge.StartNode, midNode, EdgeLabel.Neutral);
subEdge1 = new Edge(midNode, originalEdge.EndNode, EdgeLabel.Entry);
}
//Source of River
else
{
int rand = Random.Range(0, 10);
if(rand >5)
{
subEdge0 = new Edge(originalEdge.StartNode, midNode, EdgeLabel.Entry);
subEdge1 = new Edge(midNode, originalEdge.EndNode, EdgeLabel.Neutral);
CrossedEdge.Add(subEdge0);
}else
{
subEdge0 = new Edge(originalEdge.StartNode, midNode, EdgeLabel.Neutral);
subEdge1 = new Edge(midNode, originalEdge.EndNode, EdgeLabel.Entry);
CrossedEdge.Add(subEdge1);
}
}
break;
//Neutral-> Neutral + Neutral
case EdgeLabel.Neutral:
subEdge0 = new Edge(originalEdge.StartNode, midNode, EdgeLabel.Neutral);
subEdge1 = new Edge(midNode, originalEdge.EndNode, EdgeLabel.Neutral);
break;
//Exit-> Exit + Neutral
case EdgeLabel.Exit:
if (CrossedEdge.Contains(new Edge(originalEdge.StartNode, midNode)))
{
subEdge0 = new Edge(originalEdge.StartNode, midNode, EdgeLabel.Exit);
subEdge1 = new Edge(midNode, originalEdge.EndNode, EdgeLabel.Neutral);
}
else if (CrossedEdge.Contains(new Edge(midNode, originalEdge.EndNode)))
{
subEdge0 = new Edge(originalEdge.StartNode, midNode, EdgeLabel.Neutral);
subEdge1 = new Edge(midNode, originalEdge.EndNode, EdgeLabel.Exit);
}
//End of River
else
{
int rand = Random.Range(0, 10);
if (rand > 5)
{
subEdge0 = new Edge(originalEdge.StartNode, midNode, EdgeLabel.Exit);
subEdge1 = new Edge(midNode, originalEdge.EndNode, EdgeLabel.Neutral);
CrossedEdge.Add(subEdge0);
}
else
{
subEdge0 = new Edge(originalEdge.StartNode, midNode, EdgeLabel.Neutral);
subEdge1 = new Edge(midNode, originalEdge.EndNode, EdgeLabel.Exit);
CrossedEdge.Add(subEdge1);
}
}
break;
}
}
Marching cube
A Fractal Model of Mountains with Rivers
Generating RandomFractal Terrain
Simple2d Terrain With Midpoint Displacement