From 435b9f78819b7bd282fc45ac8297ca12aaec5c87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Zieli=C5=84ski?= Date: Mon, 17 Apr 2023 16:37:24 +0200 Subject: [PATCH] Start with low stifness to let zones pass through each other - typical temperature fall. --- lib/rmg/CZonePlacer.cpp | 18 +++++++++--------- lib/rmg/CZonePlacer.h | 2 ++ 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/lib/rmg/CZonePlacer.cpp b/lib/rmg/CZonePlacer.cpp index d5b733902..824d3cbda 100644 --- a/lib/rmg/CZonePlacer.cpp +++ b/lib/rmg/CZonePlacer.cpp @@ -25,10 +25,13 @@ VCMI_LIB_NAMESPACE_BEGIN class CRandomGenerator; CZonePlacer::CZonePlacer(RmgMap & map) - : width(0), height(0), scaleX(0), scaleY(0), mapSize(0), gravityConstant(0), stiffnessConstant(0), + : width(0), height(0), scaleX(0), scaleY(0), mapSize(0), + gravityConstant(5e-4f), + stiffnessConstant(3e-3f), + stifness(0), + stiffnessIncreaseFactor(1.05f), map(map) { - } int3 CZonePlacer::cords(const float3 & f) const @@ -311,9 +314,6 @@ void CZonePlacer::placeZones(CRandomGenerator * rand) Connected zones attract, intersecting zones and map boundaries push back */ - gravityConstant = 5e-4f; - stiffnessConstant = 3e-3f; - TZoneVector zonesVector(zones.begin(), zones.end()); assert (zonesVector.size()); @@ -333,8 +333,8 @@ void CZonePlacer::placeZones(CRandomGenerator * rand) TDistanceVector distances; TDistanceVector overlaps; - const int MAX_ITERATIONS = 100; - for (int i = 0; i < MAX_ITERATIONS; ++i) //until zones reach their desired size and fill the map tightly + //Start with low stiffness. Bigger graphs need more time and more flexibility + for (stifness = stiffnessConstant / zones.size(); stifness <= stiffnessConstant; stifness *= stiffnessIncreaseFactor) { //1. attract connected zones attractConnectedZones(zones, forces, distances); @@ -561,7 +561,7 @@ void CZonePlacer::separateOverlappingZones(TZoneMap &zones, TForceVector &forces float minDistance = (zone.second->getSize() + otherZone.second->getSize()) / mapSize; if (distance < minDistance) { - float3 localForce = (((otherZoneCenter - pos)*(minDistance / (distance ? distance : 1e-3f))) / getDistance(distance)) * stiffnessConstant; + float3 localForce = (((otherZoneCenter - pos)*(minDistance / (distance ? distance : 1e-3f))) / getDistance(distance)) * stifness; //negative value forceVector -= localForce * (distancesBetweenZones[zone.second->getId()][otherZone.second->getId()] / 2.0f); overlap += (minDistance - distance); //overlapping of small zones hurts us more @@ -577,7 +577,7 @@ void CZonePlacer::separateOverlappingZones(TZoneMap &zones, TForceVector &forces float3 boundary = float3(x, y, pos.z); auto distance = static_cast(pos.dist2d(boundary)); overlap += std::max(0, distance - size); //check if we're closer to map boundary than value of zone size - forceVector -= (boundary - pos) * (size - distance) / this->getDistance(distance) * this->stiffnessConstant; //negative value + forceVector -= (boundary - pos) * (size - distance) / this->getDistance(distance) * this->stifness; //negative value }; if (pos.x < size) { diff --git a/lib/rmg/CZonePlacer.h b/lib/rmg/CZonePlacer.h index f326e86a0..4750223a0 100644 --- a/lib/rmg/CZonePlacer.h +++ b/lib/rmg/CZonePlacer.h @@ -57,6 +57,8 @@ private: float gravityConstant; float stiffnessConstant; + float stifness; + float stiffnessIncreaseFactor; //float a1, b1, c1, a2, b2, c2; //CMap * map; //std::unique_ptr graph;