ওভারল্যাপিং চেনাশোনাগুলির সীমানা


21

প্লেনে কয়েকটি পয়েন্টের স্থানাঙ্ক এবং প্রতিটি পয়েন্টকে ঘিরে একটি বৃত্তের ব্যাসার্ধ দেওয়া, বৃত্তগুলি এবং বৃত্তগুলি যেখানে মিলিত হয় সেই প্রান্তগুলি উপস্থাপন করে বহুভুজ আঁকুন। সরল প্রান্তগুলি সর্বদা বৃত্ত-বৃত্ত ছেদ রেখার সাথে পড়বে , তবে এই লাইনের সম্পূর্ণ দৈর্ঘ্য অনুসরণ করতে পারে না follow

প্রতি এম্বোম্ব007 এর পরামর্শ অনুসারে 2D সাবান বুদবুদগুলির আচরণের কথা কল্পনা করুন। এটি প্রযুক্তিগতভাবে ভুল, কারণ সাবান বুদবুদ সর্বদা শক্তি হ্রাস করতে 120 ° কোণে মিলিত হত , যখন এই বৃত্তগুলি যে কোনও কোণে মিলিত হতে পারে।

এটি একটি ভোরোনাই চিত্র, বিয়োগ সংজ্ঞাযুক্ত অঞ্চল বিমান area ধন্যবাদ আন্দ্রিয়াসএটি আসলে একটি ভোরোনাই চিত্রের একটি সাধারণকরণ যা একটি পাওয়ার ডায়াগ্রাম বলে

উদাহরণ

উদাহরণস্বরূপ, দুটি পয়েন্ট এবং দুটি রেডিয়াই দেওয়া, আউটপুটটি দেখতে দেখতে এটির মতো হতে পারে:

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

অন্য একটি বিন্দু এবং ব্যাসার্ধ যুক্ত করুন এবং আউটপুটটি এর মতো দেখতে পাওয়া যাবে:

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

ইনপুট

আপনি চাইলে ইনপুটটি কাঠামো করতে পারেন। নিম্নলিখিত ইনপুট সঙ্গে ফলাফল পোস্ট করুন।

পরীক্ষা 1

  • x: 10, y: 10, r: 10
  • x: 25, y: 12, r: 8

পরীক্ষা 2

  • x: 8, y: 10, r: 6
  • x: 20, y: 8, r: 4
  • x: 18, y: 20, r: 12

আউটপুট

আউটপুট গ্রাফিকাল হওয়া উচিত এবং বহুভুজ সীমানা অন্তর্ভুক্ত করা উচিত, তবে অন্য কিছুই প্রয়োজন নেই। পয়েন্ট এবং ছেদগুলি উদাহরণগুলির মতো উপস্থাপন করার দরকার নেই।

সীমাবদ্ধতাসমূহ

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

1
বুদবুদ উল্লেখ করার জন্য আপনার শিরোনাম পরিবর্তন করা উচিত। এগুলি 2D বুদবুদগুলির মতো দেখাচ্ছে।
mbomb007

3
আপনি পয়েন্টের একটি সেট দিয়ে একটি বিমানের ভোরোনাই প্রেরণের জন্য জিজ্ঞাসা করছেন: এন.ইউইউইকিপিডিয়া
আন্দ্রেয়াস

3
একটি ভোরোনাই চিত্রতে, "প্রতিটি বীজের জন্য [বিন্দুতে] এমন একটি অঞ্চল আছে যা অন্য বীজের চেয়ে সেই বীজের নিকটবর্তী সমস্ত পয়েন্টের সমন্বয়ে গঠিত"। চিত্র 2 এর ক্ষেত্রে এটি স্পষ্টভাবে নয় 18
ডেভিডসি

2
@ আন্ড্রেস ডেভিডসি ঠিক বলেছেন, সমস্ত বৃত্ত সমান ব্যাসার্ধের
হলেই এটি ভোরোনাই

3
এই সমস্যাটি চেনাশোনাগুলির একটি পাওয়ার ডায়াগ্রামের জন্য জিজ্ঞাসা করছে ।
অ্যান্ডারস ক্যাসরগ

উত্তর:


18

পাইথন 2, 473 355 বাইট

L=input()
m=min
a,b,c,d=eval('m(%s-r for u,v,r in L),'*4%('u','v','-u','-v'))
e=(-c-a)/499.
H=lambda x,y:x*x+y*y
I=500
J=int(2-(d+b)/e)
print'P2',I,J,255
i=I*J
P=lambda(u,v,r):H(c+i%I*e+u,b+i/I*e-v)-r*r
while i:i-=1;p,k=m((P(k)/[1,k[2]][P(k)>0],k)for k in L);u,v,r=k;print int(255*m(1,[m([-p/r]+[(P(l)-p)/H(u-l[0],v-l[1])**.5for l in L-{k}]),p][p>0]/2/e))

এটি (x,y,r)স্টিডিনে টিপলস হিসাবে চেনাশোনাগুলির একটি সেট পড়ে এবং পিজিএম ফর্ম্যাটে একটি চিত্রকে স্টডআউটে আউটপুট করে। এটি প্রতিটি পিক্সেলের ডায়াগ্রামের একটি দূরত্বের ফাংশন গণনা করে এবং প্রতিটি পিক্সেলকে তার পিক্সেলের তুলনায় আনুপাতিকভাবে এক পিক্সেলের চেয়ে কম শেড করে কাজ করে।

{(10,10,10),(25,12,8)}

আউটপুট 1

{(8,10,6),(20,8,4),(18,20,12)}

আউটপুট 2

{(6, 63, 4), (16, 88, 9), (64, 94, 11), (97, 96, 3), (23, 32, 13), (54, 14, 7), (41, 81, 3), (7, 7, 4), (77, 18, 8), (98, 55, 4), (2, 56, 7), (62, 18, 5), (13, 74, 2), (33, 56, 12), (49, 48, 4), (6, 76, 2), (82, 70, 9), (21, 71, 2), (27, 5, 10), (3, 32, 6), (70, 62, 6), (74, 46, 4), (21, 60, 7), (18, 47, 7), (94, 2, 4), (39, 97, 7), (62, 63, 2), (87, 29, 8), (19, 17, 4), (61, 23, 2), (73, 1, 8), (40, 17, 13), (99, 41, 4), (81, 57, 7), (1, 68, 5), (38, 3, 4), (46, 36, 9), (4, 39, 2), (73, 77, 3), (93, 19, 10), (67, 42, 3), (96, 65, 2), (2, 16, 3), (28, 92, 3), (54, 58, 2), (39, 86, 5), (84, 82, 5), (79, 43, 4), (5, 47, 1), (34, 41, 8), (65, 5, 2), (9, 44, 3), (53, 3, 6), (1, 12, 1), (81, 95, 7), (74, 31, 2), (63, 61, 1), (35, 72, 1), (44, 71, 2), (57, 35, 5), (46, 65, 6), (57, 45, 4), (93, 94, 1), (99, 81, 13), (13, 58, 4), (68, 32, 6), (11, 2, 6), (52, 98, 7), (51, 25, 5), (84, 2, 2), (44, 92, 3), (23, 72, 2), (32, 99, 7), (13, 19, 3), (97, 29, 8), (58, 80, 3), (67, 82, 5), (59, 60, 3), (86, 87, 5), (29, 73, 2), (5, 93, 4), (42, 74, 1), (75, 85, 8), (91, 53, 5), (23, 82, 4), (19, 97, 8), (51, 88, 3), (67, 12, 6), (60, 53, 1), (66, 72, 2), (57, 64, 2), (66, 49, 2), (44, 0, 4), (11, 69, 1), (93, 60, 5), (56, 50, 3), (19, 68, 3), (64, 75, 3), (6, 17, 2), (82, 5, 2)}

আউটপুট 3

এখানে দূরত্বটির ক্রিয়াকলাপটি দৃশ্যমান করতে 32 দ্বারা ভাগ করা হয়েছে:

{(7, 9, 7), (1, 3, 2), (4, 0, 4), (9, 2, 4), (0, 8, 5)}

দূরত্ব ফাংশন ডেমো


1
শীর্ষে সংরক্ষণ করুন:exec"%s=m%s(%s for u,v,r in L);"*4%('a','in','u-r','b','ax','v-r','c','in','u+r','d','ax','v+r')
মালটিসেন

9

সি # ~ 2746

এটি সি # তে একটি সমাধান। সম্ভবত অনুকূল থেকে অনেক দূরে তবে সি # এটি আর জিতবে না। আমি নিজেই প্রমাণ করতে চেয়েছিলাম যে আমি এটি করতে পারি।

ক্রম xyr আউটপুট একটি ফাঁকা ফাঁকে ফাঁকে ফাঁকে নির্বাহী ডিরেক্টরিতে একটি ফাইল 'l.bmp' বলে উল্লেখ করে কমান্ডলাইনের মাধ্যমে ইনপুট।

প্রোগ্রাম চেনাশোনাগুলির যে কোনও পরিমাণ গ্রহণ করে।

পরীক্ষা 1: 10 10 10 25 12 8

পরীক্ষা 2: 8 10 6 20 8 4 18 20 12

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;

class Program
{
    static void Main(params string[] args) => new Program().run(args);

    class Circle
    {
        public PointF P;
        public float R;
    }

    class Line
    {
        public PointF S;
        public PointF E;
        public Circle C1;
        public Circle C2;
        public Line(Circle c1, Circle c2, PointF s, PointF e)
        {
            S = s;
            E = e;
            C1 = c1;
            C2 = c2;
        }
    }


    List<Line> lines = new List<Line>();
    List<Circle> circles = new List<Circle>();

    void run(string[] args)
    {
        for (int i = 0; i < args.Length; i += 3)
            addcircle(args[i], args[i + 1], args[i + 2]);
        circles.Sort((c1, c2) => c1.P.X.CompareTo(c2.P.X));


        int mx = (int)circles.Max(c => c.P.X + c.R) + 1;
        int my = (int)circles.Max(c => c.P.Y + c.R) + 1;



        for (int i = 0; i < circles.Count; i++)
            for (int j = i + 1; j < circles.Count; j++)
            {
                var c1 = circles[i];
                var c2 = circles[j];

                var d = dist(c1.P, c2.P);
                var a = 1 / d * sqrt((-d + c1.R - c2.R) * (-d - c1.R + c2.R) * (-d + c1.R + c2.R) * (d + c1.R + c2.R));
                var x = (sqr(d) - sqr(c2.R) + sqr(c1.R)) / (2 * d);

                var ap = angle(c1.P, c2.P);
                var la = rotate(c1.P, new PointF(c1.P.X + x, c1.P.Y + a / 2), ap);
                var lb = rotate(c1.P, new PointF(c1.P.X + x, c1.P.Y - a / 2), ap);
                var l = new Line(c1, c2, la, lb);
                lines.Add(l);
            }
        foreach (Line l in lines)
            foreach (Line lo in lines)
            {
                if (l == lo) continue;
                var intersection = intersect(l, lo);

                if (intersection != null && online(intersection.Value, l) && online(intersection.Value, lo))
                {
                    foreach (Circle circle in circles)
                    {
                        if (l.C1 == circle || l.C2 == circle)
                            continue;
                        if (dist(intersection.Value, circle.P) >= circle.R)
                            continue;

                        if (dist(l.E, circle.P) < circle.R)
                            l.E = intersection.Value;

                        if (dist(l.S, circle.P) < circle.R)
                            l.S = intersection.Value;
                    }
                }
            }


        using (Bitmap bmp = new Bitmap(mx, my))
        {
            using (Graphics g = Graphics.FromImage(bmp))
            {
                g.Clear(Color.White);
                foreach (var c in circles)
                    draw(g, c);


                for (int i = 0; i < circles.Count; i++)
                {
                    var c1 = circles[i];
                    var p = new PointF(c1.P.X + c1.R, c1.P.Y);
                    for (int j = 0; j < circles.Count; j++)
                    {
                        if (i == j) continue;
                        var c2 = circles[j];
                        for (var f = 0f; f <= 360f; f += 0.1f)
                        {
                            var pl = rotate(c1.P, p, f);
                            if (dist(pl, c2.P) <= c2.R)
                            {
                                g.DrawRectangle(new Pen(Color.White), (int)pl.X, (int)pl.Y, 1, 1);
                            }

                        }
                    }
                }


                foreach (var l in lines)
                    draw(g, l);

            }
            bmp.Save("t.bmp");
        }
    }

    private float dist(PointF p1, PointF p2) => sqrt(sqr(p1.X - p2.X) + sqr(p1.Y - p2.Y));


    bool online(PointF p, Line l)
    {
        var lx = l.S.X < l.E.X ? l.S.X : l.E.X;
        var hx = l.S.X > l.E.X ? l.S.X : l.E.X;
        var ly = l.S.Y < l.E.Y ? l.S.Y : l.E.Y;
        var hy = l.S.Y > l.E.Y ? l.S.Y : l.E.Y;

        return p.X >= lx && p.X <= hx && p.Y >= ly && p.Y <= hy;
    }

    static PointF? intersect(Line l1, Line l2)
    {
        //Line1
        float A1 = l1.E.Y - l1.S.Y;
        float B1 = l1.S.X - l1.E.X;
        float C1 = A1 * l1.S.X + B1 * l1.S.Y;

        //Line2
        float A2 = l2.E.Y - l2.S.Y;
        float B2 = l2.S.X - l2.E.X;
        float C2 = A2 * l2.S.X + B2 * l2.S.Y;

        float det = A1 * B2 - A2 * B1;
        if (det == 0)
        {
            return null; //parallel lines
        }
        float x = (B2 * C1 - B1 * C2) / det;
        float y = (A1 * C2 - A2 * C1) / det;
        return new PointF(x, y);
    }

    void addcircle(string x, string y, string r)
    {
        var SCALE = 20f;
        Circle c1 = new Circle
        {
            P = new PointF(float.Parse(x) * SCALE, float.Parse(y) * SCALE),
            R = float.Parse(r) * SCALE
        };
        circles.Add(c1);
    }

    void draw(Graphics g, Line l) => g.DrawLine(new Pen(Color.Red), l.S.X, l.S.Y, l.E.X, l.E.Y);

    PointF rotate(PointF o, PointF p, float angle)
    {
        var sa = (float)Math.Sin(angle);
        var ca = (float)Math.Cos(angle);
        var dx = p.X - o.X;
        var dy = p.Y - o.Y;

        return new PointF((ca * dx - sa * dy + o.X), (sa * dx + ca * dy + o.Y));
    }

    float angle(PointF p1, PointF p2)
    {
        var dx = p2.X - p1.X;
        if (dx == 0)
            return 0f;
        return (float)Math.Atan((p2.Y - p1.Y) / dx);
    }


    void draw(Graphics g, Circle c)
    {
        g.DrawEllipse(new Pen(Color.Blue),
                      c.P.X - c.R,
                      c.P.Y - c.R,
                      c.R * 2,
                      c.R * 2);
    }

    float sqr(float d) => d * d;
    float sqrt(float d) => (float)Math.Sqrt(d);
}

সকল ম্যাথ এখানে জড়িত উপর ভিত্তি করে তৈরি এই । লাইনগুলির স্থানাঙ্কগুলি লিঙ্কটি থেকে সূত্রগুলি ব্যবহার করা সহজ ছিল। তবে এগুলিকে দুটি জড়িত ক্রিকল কেন্দ্রগুলির মধ্যে কোণ দিয়ে ঘোরানো দরকার।

লাইনের দৈর্ঘ্য হ্রাস করতে আমি তাদের ছেদগুলি গণনা করেছি। তারপরে ছেদ করার জন্য আমি চেক করেছিলাম যে বর্তমান রেখাগুলি একটি বৃত্তে পৌঁছেছে যা "লাইনের পিতামাতা" না থাকে এবং নিজেই ছেদটি অন্তর্ভুক্ত করে। যদি এটি হয় তবে লাইনের সেই প্রান্তটি ছেদ করার জায়গায় হ্রাস পেয়েছে।

চেনাশোনাগুলি আঁকানো সহজ ছিল, "চিহ্নিত" অংশগুলি অপসারণ করা কঠিন ছিল, তাই আমি একটি "রাবার" সমাধান নিয়ে এসেছি, এটি আবার সাদা রঙে আঁকিয়ে প্রয়োজনীয় জিনিসপত্রগুলি সরিয়ে দেয়। এটা জোর করে নিষ্ঠুর ধরনের। এটি প্রতিটি চেনাশোনা প্রান্তটি ধরে হাঁটা এবং পরীক্ষা করা হয় যে পিক্সেলটি অন্য একটি বৃত্তের সীমার মধ্যে রয়েছে কিনা checking

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

সত্যিই যদি আপনি খেয়াল না করেন তবে এটি ব্যাখ্যা করার জন্য খুব কঠিন সময় কাটাচ্ছে ... ইংরাজী আমার মা টানছে না তাই এর জন্য আমি দুঃখিত।

Golfed

using System;using System.Collections.Generic;using System.Drawing;using System.Drawing.Imaging;using System.Linq;class P{static void Main(params string[]args)=>new P().R(args);class C{public PointF P;public float R;}class L{public PointF S;public PointF E;public C C1;public C C2;public L(C c1,C c2,PointF s,PointF e){S=s;E=e;C1=c1;C2=c2;}}List<L>_=new List<L>();List<C>c=new List<C>();void R(string[]args){for(int i=0;i<args.Length;i+=3)A(args[i],args[i+1],args[i+2]);c.Sort((c1,c2)=>c1.P.X.CompareTo(c2.P.X));int B=(int)c.Max(c=>c.P.X+c.R)+1;int e=(int)c.Max(c=>c.P.Y+c.R)+1;for(int i=0;i++<c.Count;)for(int j=i+1;j++<c.Count;){var f=c[i];var q=c[j];var d=D(f.P,q.P);var a=1/d*S((-d+f.R-q.R)*(-d-f.R+q.R)*(-d+f.R+q.R)*(d+f.R+q.R));var x=(F(d)-F(q.R)+F(f.R))/(2*d);var h=angle(f.P,q.P);var k=R(f.P,new PointF(f.P.X+x,f.P.Y+a/2),h);var m=R(f.P,new PointF(f.P.X+x,f.P.Y-a/2),h);var l=new L(f,q,k,m);_.Add(l);}foreach(L l in _)foreach(L o in _){if(l==o)continue;var n=I(l,o);if(n !=null && O(n.Value,l)&& O(n.Value,o)){foreach(C p in c){if(l.C1==p || l.C2==p)continue;if(D(n.Value,p.P)>=p.R)continue;if(D(l.E,p.P)<p.R)l.E=n.Value;if(D(l.S,p.P)<p.R)l.S=n.Value;}}}Bitmap r=new Bitmap(B,e);Graphics g=Graphics.FromImage(r);g.Clear(Color.White);foreach(var _ in c)D(g,_);for(int i=0;i++<c.Count;){var Q=c[i];var P=new PointF(Q.P.X+Q.R,Q.P.Y);for(int j=0;j++<c.Count;){if(i==j)continue;var G=c[j];for(var f=0f;f<=360f;f+=0.1f){var H=R(Q.P,P,f);if(D(H,G.P)<=G.R){g.DrawRectangle(new Pen(Color.White),(int)H.X,(int)H.Y,1,1);}}}}foreach(var l in _)D(g,l);r.Save("t.bmp");}float D(PointF p1,PointF p2)=>S(F(p1.X-p2.X)+F(p1.Y-p2.Y));bool O(PointF p,L l){var lx=l.S.X<l.E.X ? l.S.X : l.E.X;var hx=l.S.X>l.E.X ? l.S.X : l.E.X;var ly=l.S.Y<l.E.Y ? l.S.Y : l.E.Y;var hy=l.S.Y>l.E.Y ? l.S.Y : l.E.Y;return p.X>=lx && p.X<=hx && p.Y>=ly && p.Y<=hy;}static PointF? I(L l1,L l2){float a=l1.E.Y-l1.S.Y;float b=l1.S.X-l1.E.X;float d=a*l1.S.X+b*l1.S.Y;float e=l2.E.Y-l2.S.Y;float f=l2.S.X-l2.E.X;float g=e*l2.S.X+f*l2.S.Y;float h=a*f-e*b;if(h==0)return null;float x=(f*d-b*g)/h;float y=(a*g-e*d)/h;return new PointF(x,y);}void A(string x,string y,string r){var F=20f;C _=new C{P=new PointF(float.Parse(x)*F,float.Parse(y)*F),R=float.Parse(r)*F };c.Add(_);}void D(Graphics g,L l)=>g.DrawLine(new Pen(Color.Red),l.S.X,l.S.Y,l.E.X,l.E.Y);PointF R(PointF o,PointF p,float angle){var a=(float)Math.Sin(angle);var n=(float)Math.Cos(angle);var b=p.X-o.X;var x=p.Y-o.Y;return new PointF((n*b-a*x+o.X),(a*b+n*x+o.Y));}float angle(PointF p1,PointF p2){var a=p2.X-p1.X;if(a==0)return 0f;return(float)Math.Atan((p2.Y-p1.Y)/a);}void D(Graphics g,C c){g.DrawEllipse(new Pen(Color.Blue),c.P.X-c.R,c.P.Y-c.R,c.R*2,c.R*2);}float F(float d)=>d*d;float S(float d)=>(float)Math.Sqrt(d);}

Result1 Result2

আরও জটিল উদাহরণ (শীর্ষ বৃত্ত নেতিবাচক y মানগুলিতে পরিণত হয়)

Result3 রাবার নেই

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