Csillagrendszer legenerálása hogyan?
Írtam egy kis játékot, de van egy probléma amit nem igazán tudok megoldani.
Legenerálok gömböket amik csillagok vagy bolygók, de mivel véletlenszerű koordinátákat kapnak ezért néha egymásba érnek, mivel a véletlenszerű koordinátájuk hasonló. Hogyan lehetne olyan algoritmust írni amivel meghatározható hogy ezek között a gömbök között legyen minimális és maximális távolság? Kód nem kell csak elmélet vagy valami módszertan amit tanulmányozhatok.
Itt egy kép: [link]
A probléma nem olyan egyszerű mivel kell egy minimális távolság a csillagtól de a bolygók holdjának és kell minimális távolság a bolygójától.










Így néz ki jelenleg a kód.
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class GalaxyGenerator : MonoBehaviour {
public float galaxyWidth = 50.0f;
public int starNumbers = 20;
void Start () {
List<Star> stars = new List<Star>();
for (var i = 0; i < starNumbers; i++) {
float x = Random.Range(galaxyWidth*-1.0f, galaxyWidth);
float y = Random.Range(galaxyWidth*-1.0f, galaxyWidth);
float starRandomScale = Random.Range(0.5f, 3f);
Vector3 pos = new Vector3 (x, 0, y);
Vector3 scale = new Vector3(starRandomScale, starRandomScale, starRandomScale);
Debug.Log(i);
Star S = new Star();
//Star S = gameObject.AddComponent("Star") as Star;
//Star S = gameObject.AddComponent<Star>();
S.Init(pos,scale);
stars.Add(S);
}
Debug.Log("? "+stars.Count);
}
void Update () {
}
}
using UnityEngine;
using System.Collections;
public class Star : MonoBehaviour {
private GameObject ObjectStar;
public float Temperature;
public float Mass;
public float Size;
public Vector3 Position;
public Vector3 Scale;
//public Star(){ Debug.Log("Hmm"); }
public void Init(Vector3 pos, Vector3 scale) { InstantiateAStarInFixPosition(pos, scale); }
public void InstantiateAStarInFixPosition(Vector3 pos, Vector3 scale) {
//GameObject sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere);
GameObject sphere = Resources.Load("Prefabs/Sphere")as GameObject;
sphere.transform.localScale = scale;
GameObject star = (GameObject)Instantiate(sphere, pos, Quaternion.identity);
ObjectStar = star;
}
}





#1 vagyok
Nemhiszem hogy a random generálás és tesztelésnél van jobb algoritmus. Hacsak nem tárolod el a már foglalt helyeket és utána generálsz random értéket a maradékból, de azért ez nem triviális. Tegyük fel, hogy van egy bitmaped a foglalt középpontokkal, ebből ugyancsak úgy a legegyszerűbb egy pontot kiválasztani random módra, ha generálsz egy pontot és megnézed szabad-e. Vagy pedig megszámolod hány szabad pont van, ezzel a max értékel generálsz egy random számot és megkeresed ezt a sorszámú szabad pontot. De igazából ez elég lassú lenne amig elég üres az univerzum.... vagy tele akarod tölteni addig amig már nem fér több sehova?
Persze a random generálás+tsztelést is lehet okosan csinálni. Először is random eldöntöd melyik csillag köré akarsz rakni bolygót. Utána random előállitod a távolságot (ami megfelel, azaz nem lóg bele a csillag+min táv sugarú körbe), ekkor má csak egy szöget kell random generálnod, ami ütközhet ugyan egy már meglévő másik bolygóval.
De ha biztosra akarsz menni, akkor ugyanúgy csinálhatsz eyg bittérképet az adott távolságú kör pontjait tartalmazza, értéke pedig hogy lehet-e ott az új bolygó középpontja. De ennek a tömnek az előállitásához ugyanúgy végig kell menni a már meglévő objektumokon, azaz futásidőben nem lesz gyorsabb ha másodjára sikerült csak szabad helyet találni... sőt...





Nekem van egy ötletem.
Először ugye leteszed a csillagot középre, ez a kiindulási alap. Választasz egy távolságot, amit véletlen generálsz, hogy milyen távol legyen a naptól. Ez ugye minimum a nap és a bolygód radiusa, plusz a minimális kívánt távolság a naptól.
Ezzel kiszűrted, hogy nem érhet a naphoz.
Választasz egy szöget 0 és 359 között, hogy a nap körül hol helyezze el a korábbi távolságban. Legyen mondjuk a 0 fok a nap közepétől mért koordináta rendszer alapján az Y tengely pozitív része felé nyúló szakasz. 90 fok az X tengely pozitív felé nyúló stb.
Ezzel megoldottad, hogy véletlen helyen és véletlen távolságra legyen a naptól
Probléma még a bolygók ütközésével van. Ugye ha hasonló értékeket generáltál, akkor az azt jelenti, hogy a véletlen szám szeretné, hogy a bolygók közel legyenek. Van két megoldásod. Vagy eltolod a szöget addig egységekkel, amíg nem ütközöl újabb bolygóba, vagy a naptól vett távolsággal csinálod ugyanezt.
Ha nem túl sűrű a bolygó rendszered, akkor nem fog előfordulni, hogy hiába tologatod, sose vesz föl ütközés mentes értéket. Ha mégis, akkor ciklussal figyelned kell, hogy körbeért-e a tesztelés és ekkor a másik módszert próbálod. A távolság növelése a naptól nem okoz sűrű bolygók mellett se problémát, ha végtelen széles a pálya.





Én nem bonyolítanám ennyire túl, ha megnézed a mi naprendszerünket sem szanaszét vannak a bolygók.
Elindulsz a naptól, majd a nap rádiusza + min táv + random számra teszel egy bolygót, adsz neki random egy szöget, ahogy az előttem lévő is írta, azzal elfogatod, Unity-ben nagyon könnyű forgatni.
Aztán pedig ezt ismétled, ahogy távolodsz a napodtól.
Így 0 eséllyel ütköznek a bolygók és jó távol lesznek egymástól, realisztikus lesz, nem beszélve arról, hogy a keringés innen csak egyetlen lépés.
Gyakorlatilag poláris koordináta rendszerben randomizálsz, úgy hogy a távolságot additívan kezeled.
A collision detection, inkább fizika, amire az egyik válaszadó gondol az az metszet vizsgálat, hogy két gömb egymásba ér-e, a módszer jó de felesleges.
Kapcsolódó kérdések:
Minden jog fenntartva © 2025, www.gyakorikerdesek.hu
GYIK | Szabályzat | Jogi nyilatkozat | Adatvédelem | Cookie beállítások | WebMinute Kft. | Facebook | Kapcsolat: info(kukac)gyakorikerdesek.hu
Ha kifogással szeretne élni valamely tartalommal kapcsolatban, kérjük jelezze e-mailes elérhetőségünkön!