बीजगणितीय वक्र प्लॉटर


14

बीजगणितीय वक्र "2D-प्लेन" का एक निश्चित "1D सबसेट" है जिसे {(x,y) in R^2 : f(x,y)=0 }एक बहुपद के शून्य के सेट के रूप में वर्णित किया जा सकता है f। यहां हम 2D-प्लेन को असली प्लेन मानते हैं R^2जैसे कि हम आसानी से कल्पना कर सकते हैं कि ऐसा कर्व कैसा दिख सकता है, मूल रूप से एक ऐसी चीज जिसे आप पेंसिल से खींच सकते हैं।

उदाहरण:

  • 0 = x^2 + y^2 -1 त्रिज्या का एक वृत्त १
  • 0 = x^2 + 2y^2 -1 एक दीर्घवृत्त
  • 0 = xy एक क्रॉस आकार, मूल रूप से x- अक्ष और y- अक्ष का मिलन
  • 0 = y^2 - x एक परबोला
  • 0 = y^2 - (x^3 - x + 1)एक अण्डाकार वक्र
  • 0 = x^3 + y^3 - 3xy डेसकार्टेस के फोलियम
  • 0 = x^4 - (x^2 - y^2) एक नींबू पानी
  • 0 = (x^2 + y^2)^2 - (x^3 - 3xy^2) एक ट्राइफोलियम
  • 0 = (x^2 + y^2 - 1)^3 + 27x^2y^2 एक खगोल

कार्य

एक बहुपद f(जैसा कि नीचे परिभाषित किया गया है), और x / y- श्रेणी को देखते हुए , कम से कम 100x100 पिक्सेल की एक काली और सफेद छवि का उत्पादन करता है जो एक सफेद पृष्ठभूमि पर काली रेखा के रूप में वक्र को दर्शाता है।

विवरण

रंग : आप अपनी पसंद के दो अन्य रंगों का उपयोग कर सकते हैं, बस उन्हें अलग बताना आसान होना चाहिए।

प्लॉट : एक पिक्सेल छवि के बजाय आप इस छवि को आस्की-कला के रूप में भी आउटपुट कर सकते हैं, जहां पृष्ठभूमि "पिक्सेल" को अंतरिक्ष / रेखांकित करना चाहिए या एक अन्य चरित्र जो "खाली दिखता है" और रेखा एक चरित्र से बना हो सकता है जो दिखता है " पूर्ण "की तरह Mया Xया #

आपको एलियासिंग के बारे में चिंता करने की आवश्यकता नहीं है।

आपको केवल उन लाइनों को प्लॉट करना होगा जहां रेखा के एक तरफ से बहुपद के परिवर्तन का संकेत मिलता है (इसका मतलब है कि आप उदाहरण के लिए मार्चिंग स्क्वायर एल्गोरिथ्म का उपयोग कर सकते हैं), आपको सही तरीके से "रोग संबंधी मामलों को प्लॉट करने की ज़रूरत नहीं है, 0 = x^2जहां साइन करता है। लाइन के एक तरफ से दूसरी तरफ जाने पर परिवर्तन नहीं होता है। लेकिन लाइन निरंतर होनी चाहिए और विभिन्न संकेतों के क्षेत्रों को अलग करना चाहिए f(x,y)

बहुपद : बहुपद को (m+1) x (n+1)गुणकों की सूची (वास्तविक) गुणकों की एक मैट्रिक्स / सूची के रूप में दिया जाता है , उदाहरण के लिए गुणांक की शर्तों को उनकी स्थिति में दिया गया है:

[   1 * 1,   1 * x,   1 * x^2,   1 * x^3,  ... , 1 * x^n ]
[   y * 1,   y * x,   y * x^2,   y * x^4,  ... , y * x^n ]
[   ...  ,   ...   ,   ...   ,    ...   ,  ... ,   ...   ]
[ y^m * 1, y^m * x, y^m * x^2, y^m * x^3 , ..., y^m * x^n]

यदि आप पसंद करते हैं, तो आप मैट्रिक्स को वर्ग के रूप में मान सकते हैं (जो हमेशा आवश्यक शून्य-गद्दी के साथ किया जा सकता है), और यदि आप चाहें, तो आप यह भी मान सकते हैं कि मैट्रिक्स का आकार एडिशनल इनपुट के रूप में दिया गया है।

निम्नलिखित में, ऊपर के उदाहरणों को इस तरह परिभाषित मैट्रिक्स के रूप में दर्शाया गया है:

Circle:       Ellipse:      Parabola:  Cross:    Elliptic Curve: e.t.c
[-1, 0, 1]    [-1, 0, 1]    [ 0,-1]    [ 0, 0]   [-1, 1, 0,-1]
[ 0, 0, 0]    [ 0, 0, 0]    [ 0, 0]    [ 0, 1]   [ 0, 0, 0, 0]
[ 1, 0, 0]    [ 2, 0, 0]    [ 1, 0]              [ 1, 0, 0, 0]

एक्स-रेंज / वाई-रेंज के साथ परीक्षण के मामले:

( Pastebin पर यहाँ इतना पठनीय लेकिन बेहतर कॉपी-पेस्ट-सक्षम प्रारूप उपलब्ध नहीं है ।)

Circle:     
[-1, 0, 1]   [-2,2]   [-2,2]
[ 0, 0, 0]
[ 1, 0, 0]

Ellipse:
[-1, 0, 1]   [-2,2]   [-1,1]
[ 0, 0, 0]
[ 2, 0, 0]

Cross:
[ 0, 0]      [-1,2]   [-2,1]
[ 0, 1]

Parabola:
[ 0,-1]      [-1,3]   [-2,2]
[ 0, 0]
[ 1, 0]

Elliptic Curve:
[-1, 1, 0,-1]    [-2,2]   [-3,3]
[ 0, 0, 0, 0]  
[ 1, 0, 0, 0]  

Folium of Descartes:
[  0,  0,  0,  1]    [-3,3]   [-3,3]
[  0, -3,  0,  0]
[  0,  0,  0,  0]
[  1,  0,  0,  0]

Lemniscate:
[  0,  0, -1,  0,  1]    [-2,2]   [-1,1]
[  0,  0,  0,  0,  0]
[  1,  0,  0,  0,  0]

Trifolium:
[ 0, 0, 0,-1, 1]    [-1,1]   [-1,1]
[ 0, 0, 0, 0, 0]
[ 0, 3, 2, 0, 0]
[ 0, 0, 0, 0, 0]
[ 1, 0, 0, 0, 0]

Astroid:
[ -1,  0,  3,  0, -3,  0,  1]    [-1,1]   [-1,1]
[  0,  0,  0,  0,  0,  0,  0]
[  3,  0, 21,  0,  3,  0,  0]
[  0,  0,  0,  0,  0,  0,  0]
[ -3,  0,  3,  0,  0,  0,  0]
[  0,  0,  0,  0,  0,  0,  0]
[  1,  0,  0,  0,  0,  0,  0]

मुझे इस pdf से कुछ घटता की प्रेरणा मिली है


क्या " आपको एलियासिंग के बारे में चिंता करने की ज़रूरत नहीं है " इसका मतलब है कि हम प्रत्येक पिक्सेल को केवल इस आधार पर रंग दे सकते हैं कि क्या इसका केंद्र लाइन पर है?
पीटर टेलर

मैं अलियासिंग से संबंध नहीं देखता। लेकिन नहीं, विभिन्न संकेतों के क्षेत्रों को अलग करने वाली एक निरंतर रेखा होनी चाहिए।
दोष जूल

मैट्रिक्स mx नहीं है n, लेकिन (m+1)x है (n+1)। हम इनपुट के रूप में क्या लेते हैं: m, nया m+1,n+1? या हम चुन सकते हैं?
लुइस मेंडो

क्या हम बस एक नई विंडो में रेखांकन फ़ंक्शन दिखा सकते हैं?
आर। कप

1
@LuisMendo हाँ, अक्ष आप की तरह किसी भी दिशा में हो सकता है। (जब तक वे ओर्थोगोनल = हैं)
दोष जूल

जवाबों:


10

हास्केल, 283 275 बाइट्स

फ़ंक्शन gको मैट्रिक्स और दो श्रेणियों के साथ तर्क के रूप में बुलाया जाना चाहिए। मैट्रिक्स सिर्फ सूचियों की एक सूची है, प्रत्येक दो तत्व सूची पर्वतमाला।

import Data.List
t=transpose
u=tail
z=zipWith
l%x=sum$z(*)l$iterate(*x)1                                   --generate powers and multiply with coefficients
e m y x=[l%x|l<-m]%y                                         --evaluate the encoded polynomial
a#b=[a,a+(b-a)/102..b]                                       --create a range
g m[u,w][i,j]=unlines$v[map((0<).e m y)$u#w|y<-i#j]          --evaluate the function on the grid, get the sign
f g=u[u$u$map fst$scanl(\(r,l)c->(c==l,c))(1<0,1<0) l|l<-g]  --find +- or -+ transitions within lines
a&b|a&&b=' '|0<1='#'                                         --helper function for creating the string
v g=z(z(&))(f g)(t$f$t g)                                    --create the string

यहां अधिक दिलचस्प मामलों के लिए आउटपुट: ध्यान दें कि मुझे 100x100 से परिणाम को लगभग 40x40 तक कम करना पड़ा था, जैसे कि यह कंसोल में फिट बैठता है (बस हार्डकॉड 102 को छोटी संख्या में बदलें)। यह भी ध्यान दें कि y- अक्ष नीचे की ओर इशारा कर रहा है।


वहाँ बहुत छोटे गोल्फ आप यहाँ कर सकते हैं के एक जोड़े हैं। अंतिम पंक्ति में बाइट्स $को बचाने के लिए जब यह उपयोग किया जा सकता है तो पैरेंस का उपयोग करता है । दोनों जगह जहां आप उपयोग mapकर सकते हैं (<$>), और चूंकि आप केवल eएक बार उपयोग करते हैं, इसलिए आप (0<)इसके अंदर की परिभाषा को खींच सकते हैं । इसके अलावा eनामित किया जा सकता है (!)3 बाइट्स को बचाने के लिए।
पोस्ट रॉक गार्फ हंटर

और आपको 4 कोष्ठकों (चारों ओर और ) से छुटकारा पाने zकी vअनुमति देता है की परिभाषा में infixing । z(&)f g
पोस्ट रॉक गार्फ हंटर

आप #किसी एकल वर्ण (उदाहरण s) का नाम बदल सकते हैं और इसके बजाय सूचियों पर इसका पैटर्न मिलान कर सकते हैं g। (जैसे s[a,b]=[a,a+(b-a)/102..b];g m u i=unlines$v[m!y<$>s u|y<-s i])
पोस्ट रॉक गार्फ हंटर

6

मतलाब, 114 100 92 बाइट्स

नौकरी के लिए सही उपकरण? मैं printfएक स्ट्रिंग के रूप में बहुपद उत्पन्न करने के लिए मैटलैब करता है दिलचस्प तरीके का उपयोग करता हूं । यह बहुपद प्रदान किया जा सकता है ezplotजो निर्दिष्ट डोमेन पर निहित वक्र को प्लॉट करता है। पठनीयता के लिए कोड के बाद newlines के साथ प्रस्तुत किया गया है; जिसकी जरूरत नहीं है और आकार की ओर नहीं गिना जाता है।

function P(A,W,H,h,w)
t=0:h*w-1;
ezplot(sprintf('+%d*x^%.0f*y^%d',[A(:)';t/h;rem(t,h)]),[W,H])

विस्तार योग्य स्निपेट के रूप में गोल्फ की प्रगति।


परीक्षण मामलों का आउटपुट (पूर्ण दृश्य के लिए क्लिक करें): परीक्षण के मामलों


2
का उपयोग कर वास्तव में अच्छा समाधान sprintf/ezplot!
दोष

fixइसके बजाय का उपयोग करने से floorआपको दो अंकों की बाइट की गिनती तक पहुंचने में मदद मिल सकती है :-)
लुइस मेंडो

आप [h,w]=size(A);t=0:h*w-1;एक और तीन बाइट्स को बचाने के लिए भी इस्तेमाल कर सकते हैं !
त्रुटी

@LuisMendo वास्तव में, मैं बेहतर कर सकता हूं। मुझे इस बात का दुख था कि मतलाब के प्रिंटफ में पूर्णांक प्लेसहोल्डर नहीं है, लेकिन यह अभी भी जैसी चीजों का समर्थन करता है %.0f। इसका मतलब है कि मैं फर्श को पूरी तरह से गिरा सकता हूं और इसे printfठीक कर सकता हूं !
अल्जीमर

@flawr मैं बाद के पुनरावृत्तियों में इसका दूसरा भाग उपयोग करता हूं। मुझे लगता है कि पिछले सबसे अच्छे संस्करण के साथ मेरा प्रारूपण बिल्कुल स्पष्ट नहीं था। इस क्रिस्टल को स्पष्ट करने के लिए संपादित स्वरूपण।
अल्जीमर

6

पायथन 2, 261 बाइट्स

E=enumerate
M,[a,c],[b,d]=input()
e=(c-a)/199.
I=200
J=-int((b-d)/e-1)
print'P2',I,J,255
i=I*J
while i:i-=1;x,y=c-i%I*e,b+i/I*e;u,v,w=map(sum,zip(*((z*p/x,z*q/y,z)for q,R in E(M)for p,t in E(R)for z in[t*x**p*y**q])));print int(255*min(1,(w*w/(u*u+v*v))**.5/e))

इनपुट प्रारूप: matrix,xbounds,ybounds(जैसे [[-1,0,1],[0,0,0],[1,0,0]],[-2,2],[-2,2])। आउटपुट स्वरूप: सादा पीजीएम

यह पहले क्रम सन्निकटन d ( x , y ) = का उपयोग करके प्रत्येक पिक्सेल केंद्र से वक्र की दूरी का अनुमान लगाता है p ( x , y ) | / | ∇ पी ( एक्स , वाई ) |, ∇ जहां पी बहुपद की ढाल है पी । (यह से (दूरी है एक्स , वाई में (स्पर्श विमान के चौराहे तक) एक्स , वाई , पी ( एक्स , वाई )) के साथ xy विमान।) इसके बाद पिक्सल जहां (x , y ) वक्र की एक पिक्सेल चौड़ाई के समानुपातिक रूप से d ( x , y ) से कम है, जिसके परिणामस्वरूप अच्छी एंटीअलियासाइड लाइनें (भले ही वह आवश्यकता न हो)।

उत्पादन

यहाँ समान रेखांकन हैं जो दूरी फ़ंक्शन के साथ 16 से विभाजित हैं ताकि यह दिखाई दे सके।


रुको, तो जहां कोड में वास्तविक चित्रमय प्लॉटिंग होता है?
आर। कप

@ R.Kap कोड stdout में सादे PGM प्रारूप में एक छवि लिखता है। printछवि शीर्ष लेख के लिए एक कथन और प्रत्येक पिक्सेल के मान के लिए लूप printमें एक कथन है while
एंडर्स कासोर्ग

वाह, यह वास्तव में अच्छा है! क्या आप अपने प्लॉटिंग एल्गोरिथ्म के बारे में गहराई से थोड़ा और अधिक जाने का मन करेंगे?
दोष

@flawr मैंने स्पष्टीकरण को थोड़ा विस्तारित किया है; क्या यह आपके सवालों का जवाब देता है?
एंडर्स कासोर्ग

@AndersKaseorg जी, बहुत बहुत धन्यवाद!
निर्दोष

5

पायथन 3.5 + मेटप्लॉटलिब + नेम्पी, 352 बाइट्स:

from matplotlib.pyplot import*;from numpy import*
def R(M,S,U,r=range):N=linspace;E='+'.join([str(y)+'*'+m for y,m in[q for i,g in zip(M,[[i+'*'+p for p in['1']+['x^%d'%p for p in r(1,len(M[0]))]]for i in['1']+['y^%d'%i for i in r(1,len(M))]])for q in zip(i,g)if q[0]]]);x,y=meshgrid(N(*S,200),N(*U,200));contour(x,y,eval(E.replace('^','**')),0);show()

एक नाम दिया गया कार्य। बहुत लंबा है, लेकिन हे, मुझे बस खुशी है कि मैं इस कार्य को पूरा करने में सक्षम था। 3 इनपुट लेता है, जो m by nमैट्रिक्स हैं, इन- xअरेंज, और- yअरेंज, जो सभी ऐरे में होने चाहिए (उदाहरण के लिए, [[-1,0,1],[0,0,0],[1,0,0]],[-2,2],[-2,2])। एक नए, चित्रमय, इंटरैक्टिव विंडो में पूर्ण किए गए ग्राफ़ को आउटपुट करता है। जब मैं कर सकता हूं, तो इसे और अधिक नीचे कर दूंगा, लेकिन अभी के लिए, मैं इससे खुश हूं।

परीक्षण मामलों के लिए अंतिम आउटपुट:

अंतिम आउटपुट


5

MATL , 67 61 बाइट्स

8Wt:qwq/t2:"wid*2M1)+i:q!^]!2&!w[1IK2]&!**ss&eZS5Y62&Y+|4=0YG

यह कोड 18.5.0 भाषा में रिलीज़ होता है, जो चुनौती से पहले होता है। इनपुट वैकल्पिक m, nमापदंडों का उपयोग करता है । मैट्रिक्स में अर्धविराम पंक्ति विभाजक के रूप में हैं। सटीक इनपुट प्रारूप (उदाहरण के रूप में परबोला का उपयोग करके) है

[-1,3]
3  
[-2,2]
2
[0,-1; 0, 0; 1, 0]

कोड 255 × 255 आकार के साथ एक छवि का उत्पादन करता है । यह @Suever के MATL ऑनलाइन संकलक का उपयोग करके परीक्षण किया जा सकता है , जो कि अन्य बहुत ही रोचक विशेषताओं के साथ, ग्राफिकल आउटपुट भी शामिल है। उदाहरण के लिए देखें

यह संकलक अभी भी एक प्रयोगात्मक चरण में है। कृपया MATL चैटरूम में @Suever के किसी भी मुद्दे की रिपोर्ट करें । यदि "रन" बटन काम नहीं करता है, तो पृष्ठ को ताज़ा करने और फिर से क्लिक करने का प्रयास करें।

यदि आप ASCII आउटपुट पसंद करते हैं , तो कोड को थोड़ा संशोधित करना होगा (परिवर्तन केवल कोड के पहले दो और अंतिम चार वर्णों को प्रभावित करते हैं):

101t:qwq/t2:"wid*2M1)+i:q!^]!2&!w[1IK2]&!**ss&eZS5Y62&Y+|4<42*c

यह 100 × 100 ASCII ग्रिड का उत्पादन करता है जो *वक्र का प्रतिनिधित्व करने के लिए चरित्र का उपयोग करता है। आप इसे @Dennis 'के साथ ऑनलाइन भी आज़मा सकते हैं! मंच:

ध्यान दें कि ASCII आउटपुट का पहलू अनुपात बदल दिया गया है क्योंकि वर्ण व्यापक से थोड़े अधिक हैं।

व्याख्या

कोड पहले एक x - y ग्रिड पर दो-चर बहुपद की गणना करता है । यह प्रसारण का भारी उपयोग करता है , एक मध्यवर्ती 4D सरणी की गणना करता है जहां प्रत्येक आयाम क्रमशः x मान, y मान, x घातांक, y घातांक का प्रतिनिधित्व करता है।

उस फ़ंक्शन से, शून्य स्तर रेखा की गणना की जाती है। चूंकि चुनौती यह निर्दिष्ट करती है कि केवल साइन परिवर्तनों का पता लगाने की आवश्यकता है, कोड 2 × 2 ब्लॉक वाले लोगों के साथ 2 डी कन्वेंशन लागू करता है, और एक पिक्सेल को लाइन से संबंधित के रूप में चिह्नित करता है यदि ब्लॉक के चार मूल्यों में समान संकेत नहीं है।

8W      % Push 2^8, that is, 256. (The ASCII-output version pushes 101 instead)
t:q     % Duplicate. Push range [0 1 ... 255]
wq      % Swap. Subtract 1 to obtain 255
/       % Divide. Gives normalized range [0 1/255 2/255... 1]
t       % Duplicate
2:"     % For loop: do this twice
  w     %   Swap top two elements in the stack
  i     %   Input two-number array defining x range (resp. y in second iteration)
  d     %   Difference of the two entries
  *     %   Multiply by normalized range
  2M1)  %   Push the array again and get its first entry
  +     %   Add. This gives the range for x values (resp. y)
  i     %   Input m (n in second iteration)
  :q    %   Range [0 1 ...m-1] (resp. [0 1 ...n-1])
  !     %   Convert to column array
  ^     %   Power, element-wise with broadcast. This gives a matrix of size m×256
        %   (resp. n×256) of powers of x (resp. y) for the range of values computed
        %   previously
]       % End for loop
!       % Transpose. This transforms the n×256 matrix of powers of y into 256×n
2       % Push 2
&!      % Permute dimensions 1 and 3: transforms the 256×n matrix into a 4D array
        % of size 1×n×256×1
w       % Swap top two elements in the stack: bring 256×m matrix to top
[1IK2]  % Push vector [1 3 4 2]
&!      % Permute dimensions as indicated by the vector: transforms the m×256 matrix
        % into a 4D array of size m×1×1×256
*       % Multiply element-wise with broadcast: gives 4D array of size m×n×256×256
        % with mixed powers of x and y for at the grid of x, y values
*       % Implicitly input m×n matrix. Multiply element-wise with broadcast: gives
        % 4D array of size m×n×256×256
ss      % Sum along first two dimensions: gives 4D array of size 1×1×256×256
&e      % Squeeze singleton dimensions: gives matrix of size 256×256. This is the
        % two-variable polynomial evaluated at the x, y grid.
        % Now we need to find the zero level curve of this function. We do this by 
        % detecting when the sign of the function changes along any of the two axes
ZS      % Matrix of sign values (1, 0 or -1)
5Y6     % Predefined literal: matrix [1 1; 1 1]
2&Y+    % Compute 2D convolution, keeping only the valid (central) part
|4=     % True if absolute value of result is 4, which indicates no sign changes.
        % (The ASCII version computes a negated version of this, for better display)
0YG     % Display as image. (The ASCII-output version does the following instead:
        % multiply by 42 and convert to char. 42 is ASCII for '*', and character 0 
        % is shown as space. The 2D char array is then implicitly displayed)

सभी परीक्षण मामले

यदि आप प्रयास करना चाहते हैं, तो यहां उपयुक्त प्रारूप में सभी इनपुट हैं:

Circle:
[-2,2]
3
[-2,2]
3
[-1, 0, 1; 0, 0, 0; 1, 0, 0]

Ellipse:
[-2,2]
3
[-1,1]
3
[-1, 0, 1; 0, 0, 0; 2, 0, 0]

Cross:
[-1,2]
2
[-2,1]
2
[0, 0; 0, 1]

Parabola:
[-1,3]
3  
[-2,2]
2
[0,-1; 0, 0; 1, 0]

Elliptic Curve:
[-2,2]
3
[-3,3]
4
[-1, 1, 0,-1; 0, 0, 0, 0; 1, 0, 0, 0]

Folium of Descartes:
[-3,3]
4
[-3,3]
4
[0,  0,  0,  1; 0, -3,  0,  0; 0,  0,  0,  0; 1,  0,  0,  0]


Lemniscate:
[-2,2]
3
[-1,1]
5
[0,  0, -1,  0,  1; 0,  0,  0,  0,  0; 1,  0,  0,  0,  0]

Trifolium:
[-1,1]
5
[-1,1]
5
[0, 0, 0,-1, 1; 0, 0, 0, 0, 0; 0, 3, 2, 0, 0; 0, 0, 0, 0, 0; 1, 0, 0, 0, 0]

Astroid
[-1,1]
7
[-1,1]
7
[-1,  0,  3,  0, -3,  0,  1; 0,  0,  0,  0,  0,  0,  0; 3,  0, 21,  0,  3,  0,  0; 0,  0,  0,  0,  0,  0,  0; -3,  0,  3,  0,  0,  0,  0; 0,  0,  0,  0,  0,  0,  0; 1,  0,  0,  0,  0,  0,  0]

2
अभी भी पर्ल की तुलना में अधिक पठनीय है। महान काम, एक अच्छा ऑनलाइन संकलक भी!
19

Perl LOL की तुलना में @flawr अधिक पठनीय है । ऑनलाइन संकलक के रूप में, यह सब Sverver का काम है!
लुइस मेंडो

1
@flawr सजा के साथ अब!
लुइस मेंडू

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