/// <summary>
/// Finds the vertices that make up the area the new line is cordoning off. Implementing the Left-Right Technique I created
/// </summary>
/// <param name="startVertex">The start vertex of the line</param>
/// <param name="endVertex">The end vertex of the line</param>
/// <param name="newLine">The new Line</param>
/// <param name="lines">The list of all lines</param>
/// <param name="direction">The direction to be checking in relation to the new line. (perpendicular to the lines original vector)</param>
/// <returns>List of vertices</returns>
private List<Vertex> FindVertices(Vertex startVertex, Vertex endVertex, GameObject newLine, List<GameObject> lines, Vector3 direction)
{
// Define variables to help during the loop
List<Vertex> startVertices = new List<Vertex>();
startVertices.Add(startVertex);
GameObject startPreviousLineTaken = null;
bool startPreviousLineReversed = false;
List<Vertex> endVertices = new List<Vertex>();
endVertices.Add(endVertex);
GameObject endPreviousLineTaken = null;
bool endPreviousLineReversed = false;
bool updateStart = true; // Controls whether to update the start path or the end path this loop
int numberOfLoops = 0;
// Loop until the start and end point paths have met
while (startVertices[startVertices.Count - 1] != endVertices[endVertices.Count - 1])
{
if (numberOfLoops < 20) // Limit the number of loops to a reasonable amount
{
// Update the start and end paths on alternate loops
if (updateStart)
{
if (startVertices[startVertices.Count - 1] != null)
{
startVertices.Add(FindNextVertex(out startPreviousLineTaken, out startPreviousLineReversed, newLine, lines, direction, startVertex, startVertices[startVertices.Count - 1], endVertex, startPreviousLineTaken, startPreviousLineReversed));
}
updateStart = !updateStart;
}
else
{
if (endVertices[endVertices.Count - 1] != null)
{
endVertices.Add(FindNextVertex(out endPreviousLineTaken, out endPreviousLineReversed, newLine, lines, direction, endVertex, endVertices[endVertices.Count - 1], startVertex, endPreviousLineTaken, endPreviousLineReversed));
}
updateStart = !updateStart;
}
numberOfLoops++;
}
else break;
}
// Concat the lists after reversing the end vertices, removing the duplicate from the start of endvertices
List<Vertex> FoundVertices = startVertices;
endVertices.Reverse();
endVertices.RemoveAt(0);
FoundVertices.AddRange(endVertices);
FoundVertices.RemoveAll(x => x == null);
string logString = "Found Vertices: ";
foreach (Vertex vert in FoundVertices)
{
logString += "[" + vert.GetVector3().ToString() + "], ";
}
Debug.Log(logString);
return FoundVertices;
}
/// <summary>
/// Finds the next vertex in the given direction, a single step of the Left-Right technique
/// </summary>
/// <param name="lineTaken"></param>
/// <param name="newLine"></param>
/// <param name="lines"></param>
/// <param name="direction"></param>
/// <param name="originalVetex"></param>
/// <param name="fromVertex"></param>
/// <param name="towardsVertex"></param>
/// <param name="previousLineTaken"></param>
/// <returns></returns>
private Vertex FindNextVertex(out GameObject lineTaken, out bool reversedLineTaken, GameObject newLine, List<GameObject> lines, Vector3 direction, Vertex originalVetex, Vertex fromVertex, Vertex towardsVertex, GameObject previousLineTaken, bool previousLineReversed)
{
List<GameObject> intersectingLines = new List<GameObject>();
Vector3 towardsVector = Vector3.Normalize(towardsVertex.GetVector3() - fromVertex.GetVector3());
// Get all the lines that pass through this vertex
foreach (GameObject thisLine in lines)
{
if (thisLine != newLine && thisLine.GetComponent<LineScript>().PassesThrough(fromVertex))
{
intersectingLines.Add(thisLine);
}
}
// Find the line that moves most towards the towardsVertex after ensuring the line's directions move with the direction vector
GameObject smallestAngleLine = null;
float smallestAngleLineAngle = 360;
bool smallestAngleShouldReverse = false;
foreach (GameObject thisLine in intersectingLines)
{
bool shouldReverse = false;
Vector3 thisLineDirection = thisLine.GetComponent<LineScript>().GetNormalizedDirectionVector();
float angleTowards = Vector3.Angle(thisLineDirection, towardsVector);
// Only find whether to reverse direction on the lines we didnt take last time
if (thisLine == previousLineTaken)
{
shouldReverse = previousLineReversed;
}
else
{
// Find whether the direction of the line should be flipped
float angle = Vector3.Angle(thisLineDirection, direction);
float otherAngle = 180 - angle;
bool shouldReverseAngle = false;
if (otherAngle < angle)
{
angle = otherAngle;
shouldReverseAngle = true;
}
else if (angle == 90) // If perpendicular to direction, make sure we find out whether this line is pointing up or down
{
if (thisLineDirection != Vector3.Normalize(towardsVertex.GetVector3() - originalVetex.GetVector3()))
{
shouldReverseAngle = true;
}
}
// Get towards angles
bool shouldReverseAngleTowards = false;
float otherAngleTowards = 180 - angleTowards;
if (otherAngleTowards < angleTowards)
{
angleTowards = otherAngleTowards;
shouldReverseAngleTowards = true;
}
if (previousLineTaken != null)
{
// Take the shouldReverse of the smallest of the angles
if (angle < angleTowards)
{
shouldReverse = shouldReverseAngle;
}
else if (angleTowards < angle)
{
shouldReverse = shouldReverseAngleTowards;
}
}
else
{
shouldReverse = shouldReverseAngle;
}
}
// Check to see if this line has the smallest angle so far
if (shouldReverse)
{
thisLineDirection = Quaternion.AngleAxis(180, Vector3.up) * thisLineDirection;
angleTowards = Vector3.Angle(thisLineDirection, towardsVector);
}
if (smallestAngleLine == null || (smallestAngleLine != null && smallestAngleLineAngle > angleTowards))
{
smallestAngleLine = thisLine;
smallestAngleLineAngle = angleTowards;
smallestAngleShouldReverse = shouldReverse;
}
}
// Now i have the line to follow and the direction in which to follow it, need to get the next vertex on that line in that direction to return
Vertex nextVertex = null;
if (smallestAngleLine != null)
{
nextVertex = smallestAngleLine.GetComponent<LineScript>().GetNextVertex(fromVertex, smallestAngleShouldReverse);
}
if (nextVertex == null && smallestAngleLine != null)
{
smallestAngleLine.GetComponent<LineScript>();
smallestAngleLine.GetComponent<LineScript>().GetNextVertex(fromVertex, smallestAngleShouldReverse);
Debug.Log("UpdateArea: Couldn't find next vertex");
}
lineTaken = smallestAngleLine;
reversedLineTaken = smallestAngleShouldReverse;
return nextVertex;
}