अतिव्यापी हलकों की सीमाएं


21

एक विमान पर कई बिंदुओं के निर्देशांक को देखते हुए, और प्रत्येक बिंदु के चारों ओर एक सर्कल के त्रिज्या को हलकों और किनारों को दर्शाते हुए बहुभुज बनाएं जहां सर्कल मिलते हैं। सीधे किनारे हमेशा सर्कल-सर्कल चौराहे लाइनों के साथ गिरेंगे , लेकिन इन लाइनों की पूरी लंबाई का पालन नहीं कर सकते हैं।

प्रति mbomb007 सुझाव, 2 डी साबुन के बुलबुले के व्यवहार की कल्पना करें। यह तकनीकी रूप से गलत है, क्योंकि ऊर्जा को कम करने के लिए साबुन के बुलबुले हमेशा 120 ° कोण पर मिलेंगे , जबकि ये वृत्त किसी भी कोण पर मिल सकते हैं।

यह एक वोरोनोई आरेख है, जो एक परिभाषित क्षेत्र विमान है। धन्यवाद एंड्रियासयह वास्तव में वोरोनोई आरेख का एक सामान्यीकरण है जिसे पावर आरेख कहा जाता है।

उदाहरण

उदाहरण के लिए, दो अंक और दो रेडीआई दिए गए, आउटपुट इस तरह दिख सकता है:

यहाँ छवि विवरण दर्ज करें

एक और बिंदु और त्रिज्या जोड़ें और आउटपुट इस तरह दिख सकता है:

यहाँ छवि विवरण दर्ज करें

इनपुट

आप चाहें तो इनपुट को स्ट्रक्चर कर सकते हैं। कृपया निम्न इनपुट के साथ परिणाम पोस्ट करें।

परीक्षण 1

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

परीक्षण २

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

उत्पादन

आउटपुट चित्रमय होना चाहिए और इसमें बहुभुज सीमाएं शामिल होनी चाहिए, लेकिन कुछ और की आवश्यकता नहीं है। अंक और चौराहों का प्रतिनिधित्व करने की आवश्यकता नहीं है जैसे वे उदाहरणों में हैं।

प्रतिबन्ध

  • कोई बिंदु दूसरे सर्कल के दायरे में मौजूद नहीं होगा।
  • मानक कोडगुल्फ नियम।
  • खामियों के साथ कोई जवाब स्वीकार नहीं किया जाएगा, लेकिन इसके साथ मज़े करने के लिए स्वतंत्र महसूस करें।

1
आपको बुलबुले का उल्लेख करने के लिए शीर्षक बदलना चाहिए। ये 2D बुलबुले की तरह दिखते हैं।
mbomb007

3
आप प्लेन के वोरोनोई टेसेलेशन के लिए पॉइंट्स का एक सेट दिया है: en.wikipedia.org/wiki/Voronoi_diagram
Andreas

3
वोरोनोई आरेख में, "प्रत्येक बीज [बिंदु] के लिए एक समान क्षेत्र होता है, जिसमें उस बीज के किसी भी अन्य की तुलना में सभी बिंदु शामिल होते हैं"। यह स्पष्ट रूप से चित्रा 2 के लिए मामला नहीं है
डेविड जूल

2
@Andreas DavidC सही है, यह केवल एक वोरोनोई आरेख होगा यदि सभी वृत्त समान त्रिज्या के हों
LLlAMnYP

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

यह C # में एक समाधान है। शायद इष्टतम से बहुत दूर है, लेकिन C # इस तरह भी जीत नहीं पाएंगे। बस खुद को साबित करना था कि मैं यह कर सकता हूं।

कमांड लाइन के माध्यम से इनपुट आदेश 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);
}

यहां शामिल सभी मठ इसी पर आधारित हैं । लाइनों के निर्देशांक लिंक से सूत्रधारों का उपयोग करना आसान था। हालांकि उन्हें दो शामिल क्रिकल्स केंद्रों के बीच के कोण से घुमाया जाना आवश्यक था।

लाइनों की लंबाई कम करने के लिए मैंने उनके चौराहों की गणना की। फिर उस चौराहे के लिए मैंने जाँच की कि क्या वर्तमान लाइनें एक सर्कल में पहुंचती हैं जो "लाइन के माता-पिता" के समीप नहीं होती हैं और साथ ही चौराहे भी होते हैं। यदि ऐसा था, तो लाइन का वह छोर चौराहे के स्थान पर कम हो गया था।

हलकों को खींचना आसान था, "नोट किए गए" भागों को निकालना मुश्किल था, इसलिए मैं "रबर" समाधान के साथ आया, जो कि उस सामान को हटा देता है जिसे अब सफेद रंग से पेंट करने की आवश्यकता नहीं है। इसे मजबूर करने के लिए तरह तरह के जानवर। यह प्रत्येक सर्कल के किनारे पर चलने और चेक करने से होता है कि क्या पिक्सेल दूसरे सर्कल की सीमा के भीतर है।

प्रारंभ में मैं अपनी खुद की सर्कल-ड्राइंग विधि को रोल करना चाहता था जो केवल निर्दिष्ट कोणों के साथ सर्कल को खींचता है, लेकिन वह अच्छी तरह से बाहर नहीं निकला और कोड की और भी अधिक लाइनें ले ली।

वास्तव में एक कठिन समय यह समझाने में अगर आप ध्यान नहीं दिया ... अंग्रेजी मेरी माँ नहीं है तो मैं उसके लिए माफी चाहता हूँ।

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 कोई रबर नहीं

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.