Προς το περιεχόμενο

Προτεινόμενες αναρτήσεις

Δημοσ.

Θέλω να δημιουργήσω κάποια σημεία σε έναν 3Δ χώρο στην τύχη αλλά να μοιραστούν "δίκαια", να μην μαζευτούν δηλαδή 10 σημεία σε μια μικρή περιοχή και έχω μεγάλες κενές περιοχές.

 

καμιά ιδέα πως μπορώ να κάνω κάτι τέτοιο? (παράδειγμα είναι, μπορεί να διαφέρει)

png.png

  • Moderators
Δημοσ.

Όταν είχε χρειαστεί να το κάνω αυτό σε 2D, κλήρωνα ένα σημείο στην τύχη μέχρι το κληρωθέν σημείο να απέχει τουλάχιστον x,y από ένα άλλο σημείο. Φαντάζομαι υπάρχει πολύ πιο αποδοτικός (ίσως και πιο εύκολος) τρόπος, αλλά δε γνωρίζω αρκετά μαθηματικά γι' αυτό...

Δημοσ.

Δεν εχει διαφορα απο το 1Δ , κανε 10 rand() για το x, 10 για το y και 10 για z.

 

Edit

μαλλον τα θες σε περιοχη σαν σφαιρα, και οχι κυβο (δλδ να μην εχει κοντα στις γωνιες).

Δημοσ.

Όταν είχε χρειαστεί να το κάνω αυτό σε 2D, κλήρωνα ένα σημείο στην τύχη μέχρι το κληρωθέν σημείο να απέχει τουλάχιστον x,y από ένα άλλο σημείο. Φαντάζομαι υπάρχει πολύ πιο αποδοτικός (ίσως και πιο εύκολος) τρόπος, αλλά δε γνωρίζω αρκετά μαθηματικά γι' αυτό...

 

Σκέφτομαι να το κάνω και "χειροκίνητα" , θέλω περίπου 15-20 σημεία. απλά θα ήταν κουραστικό να γράψω τις συντεταγμένες τους.

 

Δηλαδή λες

Να συγκρίνει το κάθε σημείο με τα άλλα πόσο απέχει, αν είναι κοντά με κάποιο να σβήσει το άλλο. δεν με ενδιαφέρει να έχω έναν αποδοτικό αλγόριθμο, θα το δοκιμάσω και ελπίζω να μην υπάρξουν "λάθος διαγραφές".

  • Moderators
Δημοσ.

Όχι, εννοώ αυτό:

 

Βάλε το 1ο σημείο σε μια τυχαία θέση.

Κλήρωσε x,y,z.

Αν το σημείο που ορίζεται από τα κληρωθέντα x,y,z δεν έχει άλλο σημείο σε απόσταση x1,y1,z1 (δηλαδή σε μια σφαίρα έναν κύβο, εφ' όσον μιλάμε για 3 διαστάσεις), τότε τοποθέτησε αυτό το σημείο στο χώρο.

Αν το κληρωθέν σημείο έχει άλλα σημεία σε απόσταση x1,y1,z1, τότε κλήρωσε καινούρια x,y,z μέχρι το σημείο να μην είναι κοντά σε άλλα.

  • Like 1
Δημοσ. (επεξεργασμένο)

Όχι, εννοώ αυτό:

 

Βάλε το 1ο σημείο σε μια τυχαία θέση.

Κλήρωσε x,y,z.

Αν το σημείο που ορίζεται από τα κληρωθέντα x,y,z δεν έχει άλλο σημείο σε απόσταση x1,y1,z1 (δηλαδή σε μια σφαίρα έναν κύβο, εφ' όσον μιλάμε για 3 διαστάσεις), τότε τοποθέτησε αυτό το σημείο στο χώρο.

Αν το κληρωθέν σημείο έχει άλλα σημεία σε απόσταση x1,y1,z1, τότε κλήρωσε καινούρια x,y,z μέχρι το σημείο να μην είναι κοντά σε άλλα.

 

Σου προτείνω μια παραλλαγή του πάνω αν το κληρωθέντος x,y,z είναι ενός επιτρεπτού εύρους τιμών πχ από 15 έως 20 pixels ή points μακριά.

 

Έτσι προκύπτει ο εξής αλγόριθμος. Υποθέτουμε ότι [Χ1,Υ1,Ζ1], είναι το σημείο και [a1,a2] το επιτρεπτό εύρος απόστασης καθώς [Xn,Yn,Zn] ένα σημείο που απέχει απόσταση r από το σημείο [x1,y1,z1]

  1. Επέλεξε ένα  τυχαίο σημείο [χ1,y1,z1]
  2. Για κάθε σημείο που ικανοποιεί την συνθήκη (Xn-X1)^2+(Yn-Y1)^2+(Zn-Z1)^2<a1^2 υπολόγισε τον μέσω όρο των αποστάσεων έστω b1
  3. Πράξε ομοίως και για (Xn-X1)^2+(Yn-Y1)^2+(Zn-Z1)^2>a2^2 έστω b2
  4. Αν b1 και b2 είναι 0 τότε μετάβαση στο βήμα 1
  5. Ειδάλλως όρισε νέο σημείο με Χ1=X1+abs(b2-b1), Y1=Y1+abs(b2-b1), Z1=Z1+abs(b2-b1) και μετάβαση στο βήμα 2

Στον παραπάνω αλγόριθμό μπορείς αντί για τον μέρο όρο των αποστάσεων να παίρνεις τον μέσο όρο των x, των y και των z. Ο σκοπός είναι να το απομακρύνεις από τα σημείο που είναι κοντά και να το πας ποιο κοντά σε ένα σημείο που είναι μακριά.

 

Κάνε παραλλαγές στο παραπάνω αλγόριθμο μέχρι να σου κάνει.

 

Μια άλλη λύση είναι να ορίσεις μια:

 

  1. Ορίζω ένα εύρος τιμών που μπορεί να κυμαίνεται το X, Y, και Z και ένα εύρος αποστάσεων [a1,a2] που a1<b και a2<b που b είναι απόσταση μεταξύ [Xmin,Ymin,Zmin] και [Xmax,Ymax,Zmax] καθώς και το πλήθως των σημείων Ε.
  2. Επέλεξε ένα σημείο [X1,Y1,Z1] και βάλτο σε μια ουρά
  3. Μείωσε το Ε κατά 1
  4. Για κάθε ένα σημείο από την ουρά:
    1. Επέλεξε όλα τα σημεία που επιλύουν την ανίσωση:
      (Xn-X1)^2+(Yn-Y1)^2+(ZN-Z1)^2>=a1^2
      (Xn-X1)^2+(Yn-Y1)^2+(ZN-Z1)^2<=a1^2
      Xn<=Xmin
      Xn>=Xmax
      Yn<=Ymin
      Yn>=Ymax
      Zn<=Zmin
      Zn>=Zmax
      

      Και βάλτα σε έναν πίνακα.

    2. Ανακάτεψε τον πίνακα και επέλεξε έναν αριθμό n

    3. Όσο E-n<=0 n-=ξ όπου ξ έναν τυχαίος θετικός <n ή ένας σταθερός αριθμός που τον ορίζεις εσύ.

    4. Πάρε τα n πρώτα και βάλτα στην ουρά.

Σημείωση όπου ^ είναι ύψωση σε δύναμη.  Ελπίζω να σε βοήθησα.

Επεξ/σία από PC_MAGAS
Δημοσ.

εγω θα χωριζα την μεγαλη περιοχη σε N μικροτερες και το καθε σημειο θα επαιρνε τυχαια συντεταγμενη μονο εντος της μικρης περιοχης, δηλαδη 1 σημειο ανα μικρη περιοχη.

  • Like 4
Δημοσ.

εγω θα χωριζα την μεγαλη περιοχη σε N μικροτερες και το καθε σημειο θα επαιρνε τυχαια συντεταγμενη μονο εντος της μικρης περιοχης, δηλαδη 1 σημειο ανα μικρη περιοχη.

Έξυπνο και πολύ απλό και αποδοτικό και παραληλοποιήσιμο.

Δημοσ.

εγω θα χωριζα την μεγαλη περιοχη σε N μικροτερες και το καθε σημειο θα επαιρνε τυχαια συντεταγμενη μονο εντος της μικρης περιοχης, δηλαδη 1 σημειο ανα μικρη περιοχη.

Μπραβο αυτο ηρθα να γραψω και με προλαβες. Επισης καθε περιοχη θα μπορούσε να εχει και παραπανω απο ενα σημειο, αναλογα πως θεωρει ο OP το δικαια μοιρασμένα. Θεωρητικά θα μπορουσε να ειναι επιθυμητο να υπαρχουν σημεια και αρκετά κοντα μεταξυ τους εφόσον εχουν γεμίσει όλες οι περιοχές. Δηλαδή για 10 σημεια και 5 περιοχές, θα μπορούσε η κάθε μία να έχει 2 σημεια και θα ηταν δικαιο.

 

Επισης, για να μην ειναι πολύ πιθανό να εχεις σημεία στα άκρα των περιοχών(για να μην τυχει να εχεις σημεια κοντα μεταξυ τους απο 2 περιοχές), μπορεις να πειράξεις το random ωστε να είναι πιο σπάνιο ή να εχουν καποιο border οι περιοχές.

Δημοσ.

Δεν μου δουλεύει σωστά...

 

 

 

using UnityEngine;
using System.Collections.Generic;
using System.Collections;

public class CTest: MonoBehaviour 
{
    const int   MAX_POINTS      = 50;
    int         POINTS          = 50;
    int         MIN_DISTANCE    = 20;

    List<Vector3> randomPos = new List<Vector3>();

    float Dist(Vector3 a, Vector3 
    {
        return (Mathf.Abs(Vector3.Distance(a, ));
    }

    void Calculate()
    {
        POINTS = MAX_POINTS;
        randomPos.Clear();

        System.Random rnd = new System.Random();
        for (int i = 0; i < POINTS; i++)
        {
            // Y - is static
            randomPos.Add(new Vector3(rnd.Next(1, Screen.width / 2), 500,  rnd.Next(1, Screen.height / 2))); 
        }
    }

    void FixDistance()
    {
        for (int i = 0; i < POINTS-1; i++)
        {
            for (int j = 0; j < POINTS; j++)
            {
                if (Dist(randomPos[i], randomPos[j]) < 10f)
                {
                    randomPos.RemoveAt(j);
                    POINTS = randomPos.Count;
                }
            }
        }//for
    }

    void Start()
    {
        Calculate();
    }

    void OnGUI()
    {

        for (int i = 0; i < randomPos.Count; i++)
        {
            GUI.Label(new Rect(randomPos[i].x, randomPos[i].z, 50, 50), "*");
        }

        /*
        for (int i = 0; i < POINTS-1; i++)
        {
            for (int j = 0; j < POINTS; j++)
            {
                Debug.LogWarning(Dist(randomPos[i], randomPos[j]));
            }
        }
        */

        if (GUI.Button(new Rect(Screen.width / 2 + 200, 50, 150, 35), "Re-Calculate"))
        {
            Calculate();
        }

        if (GUI.Button(new Rect(Screen.width / 2 + 200, 100, 150, 35), "Fix Distance"))
        {
            FixDistance();
        }
        
    }
}

 

 

 

Images

 

 

 

 

img1.png

 

image2.png

 

 

 


ΥΓ: Θα κάνω αυτό που είπε το παιδί από πάνω, θα χωρίσω την περιοχή σε μικρά κουτάκια (πλέγμα) και σε κάθε κουτάκι θα βγάλω ένα Position στην τύχη.

Δημοσ.

 

ΥΓ: Θα κάνω αυτό που είπε το παιδί από πάνω, θα χωρίσω την περιοχή σε μικρά κουτάκια (πλέγμα) και σε κάθε κουτάκι θα βγάλω ένα Position στην τύχη.

 

Ναι αλλα μπορει τα σημεια σε γειτονικα κουτακια να ειναι πολυ κοντα μεταξυ τους.

Δημοσ.

Μπορεί, αλλά η διασπορά θα είναι πολύ πιο ομοιόμορφη. Δεν πρόκειται να μαζευτεί πχ το 80% των σημείων στο 1/4 του χώρου.

Αλλά ακόμα κι έτσι, θα μπορούσε να δημιουργήσει "έλξη" στο κέντρο της υποπεριοχής, κάνοντας τα σημεία να απέχουν λογαριθμικά αντί για γραμμικά από αυτό (το κέντρο).

 

BTW, ωραίο brainstorming! :-)

Δημοσ.

Εσύ απλώς βάζεις πολλά σημεία και μετά αφαιρείς αυτά που είναι κοντά :/

 

Ναι, ήταν η 1η ιδέα, μετά θα υλοποιήσω αυτό που είπε το παιδί.

 

 

Ναι αλλα μπορει τα σημεια σε γειτονικα κουτακια να ειναι πολυ κοντα μεταξυ τους.

 

Θα έχουν κάποια απόσταση μεταξύ τους τα κουτάκια + ότι μικρή η πιθανότητα όταν έχεις 40-50 σημεία.

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα
  • Δημιουργία νέου...