ভোরোনাই চিত্রের সবচেয়ে সহজ অ্যালগরিদম বাস্তবায়নের জন্য? [বন্ধ]


88

ভোরোনাই চিত্রটি কার্যকর করার জন্য সহজ অ্যালগরিদম কী কী?

আমি বিশেষত সিউডো আকারে কোনও অ্যালগরিদম খুঁজে পাইনি। দয়া করে ভোরোনাই চিত্রের অ্যালগরিদম, টিউটোরিয়াল ইত্যাদির কয়েকটি লিঙ্কগুলি ভাগ করুন


উত্তর:


32

একটি বিন্দু সেট ডেলাউন ট্রাইঙ্গুলেশন গণনা করার জন্য একটি সহজ অ্যালগরিদম প্রান্তগুলি উল্টানো হয় । যেহেতু ডেলাউন ট্রাইঙ্গুলেশনটি কোনও ভোরোনাই চিত্রের দ্বৈত গ্রাফ, তাই আপনি রৈখিক সময়ের মধ্যে ত্রিভুজ থেকে চিত্রটি তৈরি করতে পারেন।

দুর্ভাগ্যক্রমে, উল্টাপাল্টা পদ্ধতির সবচেয়ে খারাপ সময় চলার সময়টি হল ও (এন ^ 2)। ফরচুনের লাইন সুইপের মতো আরও ভাল অ্যালগরিদমগুলি ও (এন লগ এন) সময় নেয়। যদিও এটি বাস্তবায়ন করা কিছুটা জটিল। যদি আপনি অলস হন (যেমন আমি আছি) তবে আমি প্রস্তাব দেব যে একটি ডেলাউন ট্রায়াঙ্গুলেশনের বিদ্যমান বাস্তবায়ন সন্ধান করুন, এটি ব্যবহার করুন এবং তারপরে দ্বৈত গ্রাফটি গণনা করুন।

সাধারণভাবে, বিষয়টির একটি ভাল বই হ'ল ডি বার্গ এট আল-এর কম্পিউটারের জ্যামিতি


19

সবচেয়ে সহজ? এটি হ'ল ব্রুট-ফোর্স পদ্ধতির: আপনার আউটপুটে প্রতিটি পিক্সেলের জন্য, সমস্ত পয়েন্টের মাধ্যমে পুনরাবৃত্তি করুন, গণনা দূরত্ব, নিকটতমটি ব্যবহার করুন। ধীর হতে পারে তবে খুব সহজ very পারফরম্যান্স গুরুত্বপূর্ণ না হলে, এটি কাজ করে। আমি নিজেই একটি আকর্ষণীয় পরিমার্জন নিয়ে কাজ করছি, তবে এখনও অন্য কারও মত (বরং স্পষ্ট) ধারণা আছে কিনা তা অনুসন্ধান করতে চাই।


14

বায়ার-ওয়াটসন অ্যালগরিদম বুঝতে খুব সহজ। এখানে একটি বাস্তবায়ন: http://paulbourke.net/papers/triangulate/ । এটি পয়েন্টের একটি সেট জন্য একটি delaunay ত্রিভুজ্যরণ তবে আপনি এটি ব্যবহার করতে পারেন ডেলাউয়ের দ্বৈত, অর্থাৎ একটি ভোরোনাই-চিত্রের জন্য g বিটিডাব্লু সর্বনিম্ন বিস্তৃত গাছটি ডেলাউন ট্রায়াঙ্গুলেশনের একটি উপসেট।


12

ভোরোনাই চিত্রটি নির্মাণের জন্য সবচেয়ে কার্যকরী অ্যালগরিদম হ'ল ফরচুনের অ্যালগরিদম । এটি ও (এন লগ এন) এ চলে।

সিটিতে তাঁর রেফারেন্স বাস্তবায়নের একটি লিঙ্ক এখানে দেওয়া হয়েছে

ব্যক্তিগতভাবে আমি বিল সাইমনস এবং কারসন ফার্মার দ্বারা অজগর বাস্তবায়ন পছন্দ করি , যেহেতু আমার প্রসারিত করা সহজ হয়েছিল।


সি-বাস্তবায়নের লিঙ্কটি আর কাজ করবে বলে মনে হচ্ছে না :(
ফিউচারকেক

4
@ ফিউচারকেক ইন্টারনেট সংরক্ষণাগারটি উদ্ধারে: web.archive.org/web/20181018224943/http://ect.bell-labs.com/
WHo/…


9

সি এবং স্টিফান ফরচুন / শেন ও'সুলিভান থেকে সি -+ তে 2-ডি গ্রাফের জন্য অবাধে উপলভ্য ভোরোনাই বাস্তবায়ন রয়েছে:

VoronoiDiagramGenerator.cpp 

VoronoiDiagramGenerator.h 

আপনি এটি অনেক জায়গায় পাবেন। যেমন http://www.skynet.ie/~sos/masters/ এ


4
এই কোডের উপর ভিত্তি করে আমি বিস্তৃতভাবে রেফারেন্সড, অনথিভুক্ত এবং প্রায় প্রতিটি পুনঃ-বাস্তবায়নটি ভুল (বিভিন্ন ভাষায়, অনেকের ভোরোনাই প্রয়োজন, কিছু সঠিকভাবে পোর্ট করার জন্য এটি যথেষ্ট ভাল বুঝতে পারে)। আমি দেখেছি কেবলমাত্র কার্যকরী বন্দরগুলি বিজ্ঞান / একাডেমিয়া সম্প্রদায়ের এবং এগুলি ব্যাপকভাবে জটিল-জটিল ফাংশন স্বাক্ষরগুলি রয়েছে - বা ব্যাপকভাবে অনুকূলিত করা হয়েছে (যাতে তারা বেশিরভাগ উদ্দেশ্যে ব্যবহার করা যায় না) এগুলি সাধারণ প্রোগ্রামারদের দ্বারা অকার্যকর করে তোলে।
আদম

VoronoiDiagramGenerator.cpp এর কার্যকারিতা সীমিত। এটি প্রান্তের একটি নিরবচ্ছিন্ন সেট আউটপুট দেবে। এ থেকে প্রকৃত বহুভুজ উত্তোলন অ-ক্ষুদ্র। প্লাস-সাইডে, এটি একটি বাউন্ডিং আয়তক্ষেত্রের বিপরীতে একটি ক্লিপ বৈশিষ্ট্যযুক্ত, তাই কোনও অনন্ত পয়েন্ট উত্পন্ন হয় না।
ব্রাম


6

মূল প্রশ্নটি ভোরোনাইকে কীভাবে বাস্তবায়ন করতে হবে সে সম্পর্কে জিজ্ঞাসা করার সময়, আমি কি এমন একটি পোস্ট পেয়েছি যেটিতে আমি এই বিষয়ে তথ্য অনুসন্ধান করার সময় নিম্নলিখিতটি বলেছিলাম এটি আমার অনেক সময় বাঁচাতে পারত:

ভোরোনাই চিত্রগুলি বাস্তবায়নের জন্য ইন্টারনেটে প্রচুর "প্রায় সঠিক" সি ++ কোড রয়েছে। বীজ পয়েন্টগুলি খুব ঘন হয়ে গেলে বেশিরভাগই খুব কমই ব্যর্থতা শুরু করে। আমি আপনার যে পরিমাণ কোডটি খুব বেশি সময় নষ্ট করার আগে আপনার সমাপ্ত প্রকল্পে ব্যবহার করার প্রত্যাশা রেখেছি তার সাথে অনলাইনে খুঁজে পাওয়া কোনও কোড পরীক্ষা করার পরামর্শ দেব recommend

আমি অনলাইনে খুঁজে পেয়েছি সেরা প্রয়োগগুলি হ'ল এখান থেকে লিঙ্ক করা ম্যাপম্যানেজার প্রোগ্রামের অংশ: http://www.skynet.ie/~sos/mapviewer/voronoi.php এটি বেশিরভাগ ক্ষেত্রেই কাজ করে তবে আমি যখন কাজ করি তখন মাঝে মাঝে ডায়াগ্রামের দুর্নীতির বিষয়টি পাই with অর্ডার 10 ^ 6 পয়েন্ট। দুর্নীতি কীভাবে প্রকট হয়ে উঠছে আমি ঠিক তা নিয়ে কাজ করতে পারিনি।

গত রাতে আমি এটি পেয়েছি: http://www.boost.org/doc/libs/1_53_0_beta1/libs/polygon/doc/voronoi_main.htm "দ্য বুস্ট.পলিগন ভোরোনাই লাইব্রেরি"। এটি খুব প্রতিশ্রুতিবদ্ধ দেখাচ্ছে। এটি নির্ভুলতা প্রমাণ করার জন্য এটি বেঞ্চমার্ক পরীক্ষার সাথে আসে এবং দুর্দান্ত পারফরম্যান্স দেয়। গ্রন্থাগারের একটি সঠিক ইন্টারফেস এবং ডকুমেন্টেশন রয়েছে। আমি অবাক হয়েছি আমি এই লাইব্রেরিটি এর আগে খুঁজে পাইনি, সুতরাং এটি সম্পর্কে এখানে আমার লেখাগুলি। (আমি আমার গবেষণার প্রথম দিকে এই পোস্টটি পড়েছি))


4

এটি সবচেয়ে দ্রুত সম্ভব - এটি একটি সাধারণ ভোরোনাই তবে এটি দুর্দান্ত দেখাচ্ছে। এটি স্পেসকে একটি গ্রিডে বিভক্ত করে, প্রতিটি গ্রিড কোষে এলোমেলোভাবে স্থাপন করা একটি বিন্দু রাখে এবং গ্রিডের সাথে 3x3 কোষ পরীক্ষা করে এটি কীভাবে সংলগ্ন কোষগুলির সাথে সম্পর্কিত তা সন্ধান করে।

গ্রেডিয়েন্ট ছাড়াই এটি দ্রুত।

আপনি সহজেই 3 ডি ভোরোনাই কী হতে পারে তা জিজ্ঞাসা করতে পারেন। এটি জানতে আকর্ষণীয় হবে। সম্ভবত 3x3x3 কোষ এবং গ্রেডিয়েন্ট পরীক্ষা করা।

http://www.iquilezles.org/www/articles/smoothvoronoi/smoothvoronoi.htm

float voronoi( in vec2 x )
{
    ivec2 p = floor( x );
    vec2  f = fract( x );

    float res = 8.0;
    for( int j=-1; j<=1; j++ )
    for( int i=-1; i<=1; i++ )
    {
        ivec2 b = ivec2( i, j );
        vec2  r = vec2( b ) - f + random2f( p + b );
        float d = dot( r, r );

        res = min( res, d );
    }
    return sqrt( res );
}

এবং এখানে চেবিচেভ দূরত্ব একই। আপনি এখান থেকে একটি এলোমেলো 2f 2 ডি ফ্লোট শব্দ শুনতে পারেন:

https://www.shadertoy.com/view/Msl3DM

সম্পাদনা: আমি এটিকে কোডের মতো সিতে রূপান্তর করেছি

এটি কিছুক্ষণ আগে ছিল, যারা এটি তাদের সুবিধার জন্য, আমি বিশ্বাস করি এটি দুর্দান্ত:

 function rndng ( n: float ): float
 {//random number -1, 1
     var e = ( n *321.9)%1;
     return  (e*e*111.0)%2-1;
 }

 function voronoi(  vtx: Vector3  )
 {
     var px = Mathf.Floor( vtx.x );
     var pz = Mathf.Floor( vtx.z );
     var fx = Mathf.Abs(vtx.x%1);
     var fz = Mathf.Abs(vtx.z%1);

     var res = 8.0;
     for( var j=-1; j<=1; j++ )
     for( var i=-1; i<=1; i++ )
     {
         var rx = i - fx + nz2d(px+i ,pz + j ) ;
         var rz = j - fz + nz2d(px+i ,pz + j ) ;
         var d = Vector2.Dot(Vector2(rx,rz),Vector2(rx,rz));
         res = Mathf.Min( res, d );
     }
     return Mathf.Sqrt( res );
 }

4
আপনি কেন এতগুলি এক বর্ণের ভেরিয়েবলগুলি ব্যবহার করেন যা স্বতঃ ব্যাখ্যামূলক নয়? আর কি ivec2? বা vec2? এটি অপঠনযোগ্য।
shinzou

4
গুড পয়েন্ট, আমি মনে করি আমি খুব এটি সঙ্গে সারাদিন লড়াই: answers.unity3d.com/questions/638662/... কোড দিয়ে এই টেক্সট আপডেট
aliential

4

আসলে https://rosettacode.org/wiki/Voronoi_diagram এ 25 টি পৃথক ভাষার জন্য বাস্তবায়ন রয়েছে

যেমন জাভার জন্য:

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Ellipse2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.swing.JFrame;

public class Voronoi extends JFrame {
    static double p = 3;
    static BufferedImage I;
    static int px[], py[], color[], cells = 100, size = 1000;

    public Voronoi() {
        super("Voronoi Diagram");
        setBounds(0, 0, size, size);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        int n = 0;
        Random rand = new Random();
        I = new BufferedImage(size, size, BufferedImage.TYPE_INT_RGB);
        px = new int[cells];
        py = new int[cells];
        color = new int[cells];
        for (int i = 0; i < cells; i++) {
            px[i] = rand.nextInt(size);
            py[i] = rand.nextInt(size);
            color[i] = rand.nextInt(16777215);

        }
        for (int x = 0; x < size; x++) {
            for (int y = 0; y < size; y++) {
                n = 0;
                for (byte i = 0; i < cells; i++) {
                    if (distance(px[i], x, py[i], y) < distance(px[n], x, py[n], y)) {
                        n = i;

                    }
                }
                I.setRGB(x, y, color[n]);

            }
        }

        Graphics2D g = I.createGraphics();
        g.setColor(Color.BLACK);
        for (int i = 0; i < cells; i++) {
            g.fill(new Ellipse2D .Double(px[i] - 2.5, py[i] - 2.5, 5, 5));
        }

        try {
            ImageIO.write(I, "png", new File("voronoi.png"));
        } catch (IOException e) {

        }

    }

    public void paint(Graphics g) {
        g.drawImage(I, 0, 0, this);
    }

    static double distance(int x1, int x2, int y1, int y2) {
        double d;
        d = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)); // Euclidian
    //  d = Math.abs(x1 - x2) + Math.abs(y1 - y2); // Manhattan
    //  d = Math.pow(Math.pow(Math.abs(x1 - x2), p) + Math.pow(Math.abs(y1 - y2), p), (1 / p)); // Minkovski
        return d;
    }

    public static void main(String[] args) {
        new Voronoi().setVisible(true);
    }
}

3

সরল অ্যালগরিদমটি ভোরোনাই ডায়াগ্রামের সংজ্ঞা থেকে এসেছে: "এন সমেত একটি বিমানের বিভাজনকে উত্তল বহুভুজের মধ্যে বিন্দু যেমন প্রতিটি বহুভুজের ঠিক একটি উত্পন্ন বিন্দু থাকে এবং প্রদত্ত বহুভুজের প্রতিটি বিন্দু অন্য যেকোনটির তুলনায় তার উত্পন্ন বিন্দুর নিকটে থাকে। । "Wolfram থেকে সংজ্ঞা।

এখানে গুরুত্বপূর্ণ অংশটি হ'ল প্রতিটি বিন্দু অন্য যে কোনও তুলনায় উত্পন্ন বিন্দুর নিকটবর্তী হওয়া, এখান থেকে অ্যালগরিদম খুব সহজ:

  1. উত্পন্ন পয়েন্টগুলির একটি অ্যারে রাখুন।
  2. আপনার ক্যানভাসে প্রতিটি পিক্সেল দিয়ে লুপ করুন।
  3. প্রতিটি পিক্সেলের জন্য এটির নিকটতম উত্পন্ন পয়েন্টের সন্ধান করুন।
  4. আপনি যে চিত্রটি পিক্সেলের রঙ পেতে চান তার উপর নির্ভরশীল। আপনি যদি কোনও সীমানার সাথে পৃথক চিত্র আঁকতে চান তবে দ্বিতীয় থেকে নিকটতম বিন্দুতে পরীক্ষা করুন, তারপরে সীমার বর্ণের সাথে তার পার্থক্য এবং রঙটি যদি কোনও মানের চেয়ে ছোট হয় তবে তা পরীক্ষা করুন।

আপনি যদি কোনও রঙের চিত্র চান তবে প্রতিটি উত্পাদক পয়েন্টের সাথে একটি রঙ যুক্ত করুন এবং প্রতি পিক্সেলের নিকটতম জেনারেটিং পয়েন্ট সম্পর্কিত রঙের সাথে এটির রঙ দিন। এবং এটি সম্পর্কে এটি কার্যকর নয় তবে কার্যকর করা খুব সহজ।


1

0

ফরচুনের অ্যালগরিদম / সুইপ লাইন অ্যালগরিদমের ভিত্তিতে গুগল কোডে এই দুর্দান্ত সি # লাইব্রেরিটি পাওয়া গেছে

https://code.google.com/p/fortune-voronoi/

আপনার কেবল একটি তালিকা তৈরি করতে হবে। দুটি সংখ্যায় (স্থানাঙ্ক) ভাসমান হিসাবে পাস করে একটি ভেক্টর তৈরি করা যেতে পারে। তারপরে তালিকাটি ফরচুনে পাস করুন omp কমপ্লেট ভারোনোই গ্রাফ ()

আপনি এই উইকিপিডিয়া পৃষ্ঠাগুলি থেকে অ্যালগরিদমের ধারণাটি আরও কিছুটা বুঝতে পারেন:

http://en.wikedia.org/wiki/Fortune%27s_algorithm

http://en.wikedia.org/wiki/Sweep_line_algorithm

যদিও আমি যে জিনিসটি বুঝতে পারি না তা হ'ল আংশিক অসীম প্রান্তগুলির জন্য কীভাবে একটি লাইন তৈরি করা যায় (জ্যামিতি :-) স্থানাঙ্কের সম্পর্কে বেশি কিছু জানেন না)। যদি কেউ জানেন তবে দয়া করে আমাকে এটিও জানান।


4
যদিও এই লিঙ্কগুলি প্রশ্নের উত্তর দিতে পারে তবে উত্তরের প্রয়োজনীয় অংশগুলি এখানে অন্তর্ভুক্ত করা এবং রেফারেন্সের জন্য লিঙ্কটি সরবরাহ করা ভাল। লিঙ্কযুক্ত উত্তর পরিবর্তিত হলে লিঙ্কযুক্ত উত্তরগুলি অবৈধ হতে পারে।
Kmeixner

0

আপনি যদি এটি কোনও চিত্রের কাছে আঁকতে চেষ্টা করছেন তবে আপনি একটি সারি-ভিত্তিক বন্যা-ভর্তি অ্যালগরিদম ব্যবহার করতে পারেন।

Voronoi::draw(){
    // define colors for each point in the diagram;
    // make a structure to hold {pixelCoords,sourcePoint} queue objects
    // initialize a struct of two closest points for each pixel on the map
    // initialize an empty queue;

    // for each point in diagram:
        // for the push object, first set the pixelCoords to pixel coordinates of point;
        // set the sourcePoint of the push object to the current point;
        // push the queue object;

    // while queue is not empty:
        // dequeue a queue object;
        // step through cardinal neighbors n,s,e,w:
            // if the current dequeued source point is closer to the neighboring pixel than either of the two closest:
                // set a boolean doSortAndPush to false;
                // if only one close neighbor is set:
                    // add sourcePoint to closestNeighbors for pixel;
                    // set doSortAndPush to true;
                // elif sourcePoint is closer to pixel than it's current close neighbor points:
                    // replace the furthest neighbor point with sourcePoint;
                    // set doSortAndPush to true;
                // if flag doSortAndPush is true:
                    // re-sort closest neighbors; 
                    // enqueue object made of neighbor pixel coordinates and sourcePoint;

    // for each pixel location:
        // if distance to closest point within a radius for point drawing:
            // color pixel the point color;
        // elif distances to the two closest neighbors are roughly equal:
            // color the pixel to your border color;
        // else 
            // color the pixel the color of the point's region; 

}

একটি সারি ব্যবহার করে নিশ্চিত করা হবে যে অঞ্চলগুলি সমান্তরালভাবে ছড়িয়ে পড়ে এবং মোট পিক্সেল ভিজিটের সংখ্যা কমিয়ে দেয়। আপনি যদি কোনও স্ট্যাক ব্যবহার করেন তবে প্রথম পয়েন্টটি পুরো চিত্রটি পূর্ণ করবে, তবে দ্বিতীয়টি প্রথম পয়েন্টের চেয়ে আরও বেশি পিক্সেল পূরণ করবে। এটি অবিরত থাকবে, ভিজিটের সংখ্যা বাড়িয়ে দেবে। একটি FIFO সারি ব্যবহার করে পিক্সেলগুলি যাতে ক্রমানুসারে চাপ দেওয়া হয়। ফলস্বরূপ চিত্রগুলি আপনি স্ট্যাক বা সারিটি ব্যবহার করেন না কেন প্রায় একই রকম হবে, তবে সারি আলগোরিটমের বিগ-ও-এর তুলনায় কাতারের জন্য বিগ-ও লিনিয়ার (চিত্র পিক্সেলের সংখ্যার সাথে সম্পর্কিত) এর অনেক কাছাকাছি। সাধারণ ধারণাটি হ'ল অঞ্চলগুলি একই হারে ছড়িয়ে পড়বে এবং সংঘর্ষগুলি সাধারণত অঞ্চলগুলির সীমানার সাথে সামঞ্জস্যপূর্ণ পয়েন্টগুলিতে ঘটবে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.