/** * Creates a forced directed graph from https://cs.brown.edu/~rt/gdhandbook/chapters/force-directed.pdf * @param optimalDistanceModifier - increases the distance between the planets */ private void temperatureForcedDirectedGraph(float optimalDistanceModifier) { int area = frameWidth * frameHeight; List <GameObject> allPlanets = getListOfPlanets(); float optimalDistance = (float)(optimalDistanceModifier * Math.Sqrt(area / allPlanets.Count)); /** * For each planet, push them apart from the others */ foreach (GameObject currentPlanet in allPlanets) { currentPlanet.GetComponent <Planet>().setDisplacement(new Vector3(0, 0, 0)); foreach (GameObject otherPlanet in allPlanets) { if (currentPlanet.GetInstanceID() != otherPlanet.GetInstanceID()) { Vector3 differenceVector = currentPlanet.transform.position - otherPlanet.transform.position; updateDisplacement(differenceVector, optimalDistance, currentPlanet, false); } } } /** * For each edge, pull their two planets closer towards each other */ List <PlanetLine> graphEdges = new List <PlanetLine>(); foreach (GameObject currentPlanet in allPlanets) { List <GameObject> connections = currentPlanet.GetComponent <Planet>().getConnectedObjects(); foreach (GameObject otherPlanet in connections) { PlanetLine edge = new PlanetLine(currentPlanet, otherPlanet); if (!graphEdges.Contains(edge)) { graphEdges.Add(edge); Vector3 differenceVector = currentPlanet.transform.position - otherPlanet.transform.position; updateDisplacement(differenceVector, optimalDistance, currentPlanet, true, true); updateDisplacement(differenceVector, optimalDistance, otherPlanet, true); } } } // Move the planets by their calculated forces foreach (GameObject currentPlanet in allPlanets) { Vector3 currentPos = currentPlanet.transform.position; Vector3 displacementVector = currentPlanet.GetComponent <Planet>().getDisplacement(); currentPlanet.transform.position = currentPos + ((displacementVector.normalized) * Math.Min(displacementVector.magnitude, getTemp())); } }
private void removeCrossingEdges(List <PlanetLine> crossings) { for (int i = 0; i < crossings.Count; i += 2) { if (crossings.ElementAtOrDefault(i) != null && crossings.ElementAtOrDefault(i + 1) != null) { PlanetLine firstLine = crossings.ElementAtOrDefault(i); PlanetLine secondLine = crossings.ElementAtOrDefault(i + 1); /** * crossing edges look like this fixed result should look like this * a a | / \ | x ---- y x y | \ / | b b */ GameObject xPlanet = firstLine.firstPlanet; GameObject yPlanet = firstLine.secondPlanet; GameObject aPlanet = secondLine.firstPlanet; GameObject bPlanet = secondLine.secondPlanet; // Remove the crossing edges by destroying the trade routes between the planets xPlanet.GetComponent <Planet>().removeConnectedPlanet(yPlanet); yPlanet.GetComponent <Planet>().removeConnectedPlanet(xPlanet); aPlanet.GetComponent <Planet>().removeConnectedPlanet(bPlanet); bPlanet.GetComponent <Planet>().removeConnectedPlanet(aPlanet); // Connect the planet to the previously conflicting trade route planets addPlanet(xPlanet, aPlanet); addPlanet(xPlanet, bPlanet); addPlanet(yPlanet, aPlanet); addPlanet(yPlanet, bPlanet); } } }
/** * Returns whether or not the intersection has already been identified (since each trade route is two-way, there are duplicates) */ private bool intersectionAlreadyFound(PlanetLine firstLine, PlanetLine secondLine, List <PlanetLine> intersectionsList) { return(intersectionsList.Contains(firstLine) && intersectionsList.Contains(secondLine)); }