ওভারল্যাপ না করে এমন এন্টিটি এলোমেলোভাবে কীভাবে স্থাপন করবেন?


11

আমি যে গেমটি বিকাশ করছি তার জন্য আমি এলোমেলোভাবে উত্পন্ন পরিবেশ তৈরি করছি। আমি ব্যবহার OpenGLএবং কোডিং করছি Java

আমি আমার পৃথিবীতে এলোমেলোভাবে গাছ রাখার চেষ্টা করছি (একটি বন তৈরি করতে), তবে আমি চাই না মডেলগুলি ওভারল্যাপ হয়ে যায় (যা ঘটে যখন দুটি গাছ একে অপরের খুব কাছাকাছি স্থাপন করা হয়)। এখানে আমি যা বলছি তার একটি চিত্র:

এখানে চিত্র বর্ণনা লিখুন

আমি প্রয়োজনে আরও কোড সরবরাহ করতে পারি তবে প্রয়োজনীয় স্নিপেটগুলি এখানে। আমি আমার জিনিসগুলি একটি ArrayListসাথে সঞ্চয় করছি List<Entity> entities = new ArrayList<Entity>();। তারপরে আমি সেই তালিকায় যুক্ত হয়ে যাচ্ছি:

Random random = new Random();
for (int i = 0; i < 500; i++) {
    entities.add(new Entity(tree, new Vector3f(random.nextFloat() * 800 - 400, 
    0, random.nextFloat() * -600), 0, random.nextFloat() * 360, 0, 3, 3, 3);
}

যেখানে প্রতিটি Entityনীচের বাক্য গঠন অনুসরণ করে:

new Entity(modelName, positionVector(x, y, z), rotX, rotY, rotZ, scaleX, scaleY, scaleZ);

rotXx- অক্ষ বরাবর ঘূর্ণন এবং scaleXএক্স-দিকের স্কেল ইত্যাদি

আপনি দেখতে পাচ্ছেন যে আমি এই গাছগুলিকে এলোমেলোভাবে স্থান এবং অবস্থানের random.nextFloat()জন্য রেখে দিচ্ছি xএবং zসীমার সীমাবদ্ধ করছি যাতে গাছগুলি কাঙ্ক্ষিত স্থানে প্রদর্শিত হবে। তবে আমি এই অবস্থানগুলিকে একরকম নিয়ন্ত্রণ করতে চাই, যাতে এটি যদি আগের গাছের খুব কাছাকাছি একটি গাছ রাখার চেষ্টা করে তবে এটি একটি নতুন এলোমেলো অবস্থান পুনরায় গণনা করবে। আমি ভাবছিলাম যে প্রতিটি গাছেই Entityঅন্য একটি ক্ষেত্র থাকতে পারে, যেমন treeTrunkGirth, এবং যদি একটি গাছ অন্য গাছের অবস্থানের এবং এর মধ্যবর্তী স্থানে স্থাপন করা হয় treeTrunkGirthতবে এটি নতুন অবস্থান পুনরায় গণনা করবে। এটি সম্পাদন করার কোনও উপায় আছে?

আমি আরও কোড স্নিপেট এবং প্রয়োজনীয় হিসাবে বিশদ যুক্ত করে খুশি।


3
পোইসন ডিস্কের স্যাম্পলিংয়ের কাজটি করা উচিত। এটি এর পক্ষে সেরা কিনা এবং কখনই এটি বাস্তবায়িত / ব্যবহার করা হয়নি তা জানেন না তবে কমপক্ষে একটি ভাল সূচনা হিসাবে মনে হচ্ছে। এই নিবন্ধটি দেখুন: devmag.org.za/2009/05/03/poisson-disk-sampling
মঙ্গলবার

@ মার্স বাহ, সেই লিঙ্কটি অত্যন্ত সহায়ক, ধন্যবাদ। আমি কী করতে পারি তা দেখতে পাব এবং সম্ভবত আমার নিজের উত্তর নিয়ে ফিরে আসব।
wcharit

@ পিকেলেক হ্যাঁ, আমি মনে করি যে আপনি যে প্রশ্নটি যুক্ত করেছেন সেটি একটি নকল। আমি কি অন্য প্রশ্নের মতো "তারকা মানচিত্রের" ক্ষেত্র হিসাবে XZ-বিমানটি ব্যবহার করব ?
wcharit

হ্যাঁ, আপনার ক্ষেত্রে xz বিমানটি ব্যবহার করুন । এছাড়াও, treeTrunkGirthগাছ রাখার জন্য ন্যূনতম দূরত্ব নির্ধারণের জন্য ধ্রুবকের পরিবর্তে ব্যবহার করুন যদি তাদের পরিবর্তনের প্রয়োজন হয়।
পিকালেক

@ পিকেলেক আপনি যদি কোনও উত্তরে এটি যোগ করেন তবে আমি এটিকে সেরা হিসাবে নির্বাচন করব। সাহায্যের জন্য ধন্যবাদ.
wcharit

উত্তর:


15

একটি পোইসন-ডিস্কের নমুনা বিতরণ আপনাকে এলোমেলো পয়েন্টগুলি সর্বনিম্ন দূরত্বে পৃথকভাবে নির্বাচন করতে দেয়। আপনার পরিস্থিতি এই প্রশ্নের অনুরূপ , তবে যেহেতু আপনার গাছগুলি আদর্শ পয়েন্ট নয় তবে আপনাকে নিম্নোক্তভাবে দূরত্ব যাচাই করতে হবে: সম্ভাব্য নতুন গাছ এবং একটি বিদ্যমান গাছের মধ্যে দূরত্ব অবশ্যই তাদের রেডির যোগফলের চেয়ে কম হতে হবে ।

ব্রিডসনের অ্যালগরিদম ও (এন) এ দক্ষতার সাথে সমস্যাটি সমাধান করতে পারে তবে পরিবর্তনশীল দূরত্বের জন্য এটি সামান্য তুচ্ছভাবে বলা যায়। যদি আপনার প্যারামিটারগুলি নিম্নমানের থাকে & / অথবা আপনি নিজের অঞ্চলটি পূর্বাভাস দিয়ে থাকেন তবে একটি বর্বর শক্তি সমাধান আপনাকে ঠিক সেইভাবেই পরিবেশন করতে পারে। এখানে কিছু নমুনা কোড যা ব্রুটে সমস্ত পূর্ববর্তী স্থাপনিত গাছের বিরুদ্ধে প্রতিটি সম্ভাব্য নতুন গাছ বসানো পরীক্ষা করে সমস্যাটি জোর করে:

public static class SimpleTree{
    float x;
    float z;
    float r;

    public SimpleTree(Random rng, float xMax, float zMax, float rMin, float rMax){
        x = rng.nextFloat() * xMax;
        z = rng.nextFloat() * zMax;
        r = rng.nextFloat() * (rMax-rMin) + rMin;
    }
}

private static ArrayList<SimpleTree> buildTreeList(float xMax, float zMax, 
        float rMin, float rMax, int maxAttempts, Random rng) {
    ArrayList<SimpleTree> result = new ArrayList<>();

    SimpleTree currentTree = new SimpleTree(rng, xMax, zMax, rMin, rMax);
    result.add(currentTree);

    boolean done = false;
    while(!done){
        int attemptCount = 0;
        boolean placedTree = false;
        Point nextPoint = new Point();
        SimpleTree nextTree = null;
        while(attemptCount < maxAttempts && !placedTree){
            attemptCount++;
            nextTree = new SimpleTree(rng, xMax, zMax, rMin, rMax);
            if(!tooClose(nextTree, result)){
                placedTree = true;
            }
        }
        if(placedTree){
            result.add(nextTree);
        }
        else{
            done = true;
        }
    }

    return result;
}

private static boolean tooClose(SimpleTree tree, ArrayList<SimpleTree> treeList) {
    for(SimpleTree otherTree : treeList) {
        float xDiff = tree.x - otherTree.x;
        float zDiff = tree.z - otherTree.z;

        float dist = (float)Math.sqrt((xDiff * xDiff) + (zDiff * zDiff));
        if(dist < tree.r + otherTree.r){
            return true;
        }
    }        
    return false;
}

নিম্নলিখিত পরামিতি সহ:

 maxAttempts = 500;
 width = 300;
 height = 200;
 minSize = 2;
 maxSize = 15;

আমি এলোমেলোভাবে 400 সেকেন্ডের মধ্যে 400-450 গাছের মধ্যে স্থান এবং রেন্ডার করতে সক্ষম হয়েছি। এখানে একটি উদাহরণ: এখানে চিত্র বর্ণনা লিখুন


এটি কি পোসন ডিস্কের নমুনা ব্যবহার করছে?
wcharit

হ্যাঁ, আমি এটিকে স্পষ্ট করতে সম্পাদনা করেছি।
পিকেলেক

Math.pow tree.r + other tree.r2, math.sqrt এর পরিবর্তে ব্যবহার করার চেষ্টা করুন , স্কয়ার্ট সাধারণত পা এর চেয়ে ধীর হয়
ফেরিবিগ

1
@ ফেরিবিগ বর্গক্ষেত্রের দূরত্বের তুলনা দ্রুততর, তবে এটি সত্য যে এটি একটি নিষ্ঠুর শক্তি অ্যালগরিদম এবং এখনও ও (এন ^ 2) হবে তা পরিবর্তন করে না। যদি দ্রুত সমাধানের প্রয়োজন হয় তবে ব্রিডসনের অ্যালগরিদম ব্যবহার করুন। এছাড়াও, ব্যবহার Math.pow(x,2)অগত্যা কোনো ভালো / ব্যবহার না করে ভিন্ন নয় x*xযেমন এখানে আলোচনা
পিকালেক

1
ভূখণ্ডে এবং কিছু শালীন বিস্তার এবং কোনও ওভারল্যাপ নিশ্চিত করার ক্ষেত্রে আমার একই রকম সমস্যা ছিল। আমি আসলে একটি পরিবর্তন করেছি, আমার সংস্করণে ট্রেস / ব্রাশটি এলোমেলোভাবে অঞ্চল অঞ্চল জুড়ে ছড়িয়ে পড়েছে। আমি একে অপরের বিরুদ্ধে প্রতিটি আইটেমের দূরত্বগুলি পরীক্ষা করার জন্য এটি একটি ফাংশন পোস্ট চালনা করি, যেখানে তারা খুব কাছে ছিল আমি তাদের আলাদা করে দিয়েছিলাম। এটি সম্ভবত এই অঞ্চলে অন্যান্য গাছের উপর চাপিয়ে দেবে। আমার কোনও সংঘর্ষ না হওয়া পর্যন্ত আমি এটি পুনরাবৃত্তি করেছি। এটি ধীরে ধীরে তবে আমার কাছে বোনাস হিসাবে যা ছিল তা ক্লিয়ারিংয়ের মতো জিনিস ছিল (সর্বত্র আবৃত নয়!) এবং গাছের ঘনত্ব আরও "আকর্ষণীয়" বলে মনে হয়েছিল।
আর্নিডিংগো 21
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.