2色の重なり合う円


22

次の入力を適切な形式で選択するプログラムまたは関数を作成します。

  • 生成する画像の幅と高さを定義する2つの正の整数WとH。

  • 画像の色付けに使用される2つのRGBカラーC1およびC2。

  • 画像の平面内で(r, x, y)半径rと中心x, yを持つ円を定義するフォームの3タプルのリスト。rは正の整数であり、xおよびyは任意の整数です。画像の左上のピクセルは0, 0x軸が右に増加し、y軸が下に増加します。

重複するすべての円によって定義される2つの隣接領域が同じ色にならないように、 C1およびC2で色付けされた寸法W x Hの画像を出力します

例:入力が

W = 300
H = 200
C1 = (255, 200, 0)
C2 = (128, 0, 255)
Circles = (25, 50, 80), (40, 80, 120), (300, -100, 6), (17, 253, 162)

円の境界は次のようになります。

例1円の境界

円によって作成された画像には、6つの異なる連続した領域があります。各領域は、隣接する2つの領域が同じ色にならないように、C1(黄色)またはC2(紫色)で色付けする必要があります。

これを行うには2つの方法がありますが、唯一の違いは色を交換することです。

例1出力1 例1出力2

したがって、これら2つの画像のいずれかは、入力例の有効な出力になります。

2つの黄色の領域が互いに隣接しているため、このようなものは無効な出力になります。

出力画像は次のガイドラインに従う必要があります。

  • C1とC2に加えて、黒または白などの3番目の中間色は、5ピクセル以下の厚さであれば円の境界に使用できます。(上記の例では、黒の1ピクセルの太い境界が存在します。)

  • ただし、円の境界は必要ありません。領域は互いに直接隣接する場合があります。

    例1出力3 例1出力4

    これらは両方とも、上記の例に対する別の有効な出力です。

  • 円は、円描画アルゴリズムまたはグラフィックライブラリが提供するものを使用して、合理的に可能な限り正確でなければなりません。

  • 一般に、ピクセルの完全性は必要ありませんが、入力パラメーターが等しく大きく拡大されると、結果の画像はますます正確になるはずです。

  • アンチエイリアスは許可されていますが、必須ではありません。

  • 背景のグリッド線または軸ラベルなどは許可されません。

バイト単位の最短コードが優先されます。

その他の例

これらはすべて、異なる円のセットでこれらの入力を使用しています。

W = 100
H = 60
C1 = (255, 0, 0)
C2 = (0, 0, 255)

いずれの例でも、色を入れ替えても有効のままにすることができます。

Circles =
A. empty list
B. (13, 16, 20)
C. (30, 16, 20)
D. (200, 16, 20)
E. (42, 50, 20)
F. (42, 50, 20), (17, 40, 30)
G. (42, 50, 20), (17, 20, 30)
H. (42, 50, 20), (17, 10, 30), (10, 50, 30)
I. (42, 50, 20), (17, 10, 30), (35, 50, 20)
J. (18, 36, 40), (18, 63, 40), (18, 50, 20)
K. (100, -10, -20), (60, 50, -10)
L. (18, 36, 40), (18, 63, 40), (18, 50, 20), (14, 50, 20), (5, 50, 18), (20, 0, 0), (70, 22, 0), (10000, -9970, 0), (135, 100, -80) 

A. ex A B. ex B C. ex C D. ex D
E. EXE F. ex F G. ex G H. ex H
I. ex I J. ex J K. ex K L. ex L

出力がこれらすべての例と同様に動作することを確認してください。


良さそうに見えますが、asciiで出力できます。たとえば、C1は1で、C2は0です。
マシュー

@MatthewRohいいえ。これは便利ですが、画像が必要です。
カルビンの趣味

1
それでは、私は数えることができると思いますtikz
ウィートウィザード

1
@ MatthewRoh、netpbmはこのサイトで一般的に使用される画像形式です。
ピーターテイラー

2
@ルイスOK そのような小さな入力変動やy軸の上昇は問題ありません。
カルビンの趣味

回答:


14

Mathematica、165バイト

ContourPlot[Cos@Tr[Boole[Norm[{x,y}-#2]<#]Pi&@@@#4],{x,0,#},{y,0,#2},PlotPoints->5!,AspectRatio->Automatic,Frame->False,ContourShading->RGBColor@@@#3,Contours->{0}]&

4つの引数を取る純粋な関数:幅、高さ(両方の整数)、0から1の間の数字のトリプルの順序ペア(2つのRGB色を表す)、および{r, {x, y}}半径と中心を記録するフォームの項目のリストサークル。たとえば、OPの最初の例はargumentsで呼び出されます[300, 200, {{1, 0.784, 0}, {0.5, 0, 1}}, {{25, {50, 80}}, {40, {80, 120}}, {300, {-100, 6}}, {17, {253, 162}}}]。Mathematicaでは正のy軸が上を向いています。

Norm[{x,y}-#2]<#ポイントが特定の円内にあるかどうかを検出します。またはをまたはにBoole[...]Pi変換します。すべての入力円でそれらのπ / 0を計算した後、それらを合計し、πの偶数倍を1に、πの奇数倍を–1に変換します。次に、値がより大きいか小さいかに応じて、平面の適切な領域を2色で色付けします。円を円のように見せます。適切な精度を提供します(本当に素晴らしい写真が必要な場合は、それを大幅に強化してください!); 軸を取り除きます。そして、輪郭の入力色を使用しています。TrueFalseπ0TrCosContourPlot[...,Contours->{0}]0AspectRatio->AutomaticPlotPoints->5!9!Frame->FalseContourShading->RGBColor@@@#3

最初の色のペア(見栄えが良いため)のサンプル出力、ただし最後の円のセット:

サンプル出力


11

JavaScript / SVG / HTML5、219バイト

f=// for demo
(w,h,b,f,a)=>`<svg width=${w} height=${h}><rect width=${w} height=${h} fill=rgb(${b}) /><path fill=rgb(${f}) fill-rule=evenodd d=${a.map(([r,x,y])=>[`M`+x,y-r+`a`+r,r,0,0,0,0,r+r+`a`+r,r,0,0,0,0,-r-r]).join``} /></svg>`
;//demo
[[`A`, []],
 [`B`, [[13, 16, 20]]],
 [`C`, [[30, 16, 20]]],
 [`D`, [[200, 16, 20]]],
 [`E`, [[42, 50, 20]]],
 [`F`, [[42, 50, 20], [17, 40, 30]]],
 [`G`, [[42, 50, 20], [17, 20, 30]]],
 [`H`, [[42, 50, 20], [17, 10, 30], [10, 50, 30]]],
 [`I`, [[42, 50, 20], [17, 10, 30], [35, 50, 20]]],
 [`J`, [[18, 36, 40], [18, 63, 40], [18, 50, 20]]],
 [`K`, [[100, -10, -20], [60, 50, -10]]],
 [`L`, [[18, 36, 40], [18, 63, 40], [18, 50, 20], [14, 50, 20], [5, 50, 18], [20, 0, 0], [70, 22, 0], [10000, -9970, 0], [135, 100, -80]]]
 ].forEach(([c, a])=>document.write(`<nobr><tt>&nbsp;${c}.&nbsp;</tt>${f(100, 60, [255, 0, 0], [0, 0, 255], a)}</nobr><wbr>`));


10

BBC Basic、120 117バイト

インタプリタをhttp://www.bbcbasic.co.uk/bbcwin/bbcwin.htmlからダウンロードしてください

I.w,h,R,G,B,r,g,b:V.22,4,19;16,r,g,b,275;16,R EORr,G EORg,B EORb,24,0;0;w;h;16
5I.r,x,y:V.25,4,x;h-y;25,154,r;0;:G.5

BBC Basicには、OR、AND、XORなどの基本的な論理演算に従ってラスターグラフィックスをプロットできるさまざまなカラーモードがあります。

また、パレットの再プログラミングもサポートしています。たとえば、ここでは、2色の画像の色を4096色のいずれかに再プログラミングできます。ここで使用される実装には、元のBBC実装とはいくつかの(文書化されていない)違いがあり、EOR演算子は必要ありません。

非ゴルフ

  INPUTw,h,R,G,B,r,g,b:                           :REM Input size and colours
  VDU22,4                                         :REM Change to MODE 4 (2 colours) as the default mode gives odd behaviour
  VDU19,0,16,r,g,b,19,1,16,R EORr,G EORg,B EORb   :REM Reprogram the colours to R,G,B and R^r,G^g,B^b
  VDU24,0;0;w;h;16                                :REM Setup a graphics viewport of the right size, and "clear" it to change background colour
5 INPUTr,x,y                                      :REM take input coordinates
  VDU25,4,x;h-y;                                  :REM move to x,y (h-y required as BBC BASIC y axis increases upward, reverse of spec)
  VDU25,154,r;0;                                  :REM draw circle in "logical inverse colour" of existing pixels (this implementation seems however to XOR with colour 1 instead)
  GOTO5                                           :REM repeat infinitely until user presses escape

典型的な出力画面

単位で10倍、ピクセルで5倍に拡大されたサンプル画像(BBC基本は1ピクセル= 2単位を使用します)

ここに画像の説明を入力してください


10

MATL30 29 25バイト

2ZG:i:!J*+2&!-|i<so2&!1YG

入力形式:

  • 0〜255の値の行列としてのカラーマップ。各行は色を定義します
  • W
  • H
  • 複素数値としての1ベースの中心座標の列ベクトル(xは実数部、yは虚数部)
  • 半径の列ベクトル。

MATL Online試しくださいまたは、最後のテストケースを確認します。(インタプリタはまだ実験段階です。ページを更新して、機能しない場合は再試行する必要があります)。

説明

このコードは、複素数を使用して点のグリッドを定義し、距離を計算し、ブロードキャストで配列操作を多用します。

2ZG    % Implicitly input matrix of colors. Set as colormap
:      % Implicitly input W. Push [1 2 ... W]
i:     % Input H. Push [1 2 ... H]
!J*    % Transpose, multiply by 1i
+      % Add element-wise with broadcast. Gives H×W grid of points as
       % complex numbers, 1-based 
2&!    % Permute first dimension with the third. Gives a 1×W×H array
-|     % Implicitly input center coordinates. Subtract grid from them,
       % element-wise with broadcast. Gives a C×H×W array, where C is the
       % number of circles
i      % Input column vector of circle radii
<      % Less than, element-wise with broadcast
so     % Sum along first dimension, modulo 2. Gives a 1×W×H array
2&!    % Permute first dimension with the third. Gives a a H×W array
1YG    % Display as scaled image

2
これらのバイトを保存します!:D
グレッグマーティン

1
@GregMartinあなたは正しい。4バイトを節約できるとき、誰が優雅さを気にしますか!:-)完了
ルイスメンドー

1
@LuisMendo codegolfの方が短くなればなるほど、くなります。;)
ケビンクルーッセン

6

pypngを使用するPython 、140 138バイト

import png
f=lambda W,H,c,d,C:png.from_array([[[c,d][sum(abs(x-X+1j*(y-Y))<r for r,x,y in C)%2]for X in range(W)]for Y in range(H)],'RGB')

使用例:

W = 100
H = 60
C1 = (255, 0, 0)
C2 = (0, 0, 255)
Circles = (18, 36, 40), (18, 63, 40), (18, 50, 20), (14, 50, 20), (5, 50, 18), (20, 0, 0), (70, 22, 0), (10000, -9970, 0), (135, 100, -80)
f(W, H, C1, C2, Circles).save('test.png')

2バイトを節約してくれたxnorに感謝します。


コードゴルフへようこそ!点が円の中にあるかどうかを確認するための1つの秘isは、複雑なノルムを使用することですabs(x-X+1j*(y-Y))<r
-xnor

3

数学(非競合)

(PPCGでLaTeXを行う方法を知っているので、LaTeXからpngへのツールを使用しました)

説明

複数の円方程式の積((x-a)^2+(y-b)^2-r^2)> = 0は、この質問に必要なグラフを作成します。方程式でnは、は配列のサイズで(x, y or r)_kあり、k番目の(x, y, or r)要素です。

(0,0,2),(2,2,2)

(WolframAlphaに感謝)

(WolframAlphaによる不等式プロット)

WolframAlphaの方程式を取得/実行

スクリプトの取得:完了

スクリプトの実行:まだ完了していません

Mathematicaで動作するようになりました...


これは有効かしら?
マシュー盧

その入力を与えられた形で出力をプロットする特定の既存のインタプリタをリストする必要があります。それはその中のバイトをカウントすることを可能にします。現時点では、インタープリターに結び付けられていないため、方程式を表現するための特定の形式に結び付けられていないため、表記法は非公式であり、客観的に数えることができないという問題があります。方程式のグラフをプロットするためのプログラムはたくさんあるので、簡潔な入力形式のグラフを見つける価値があるかもしれません。

@ ais523ああ。WolframAlphaで動作するようにします。
マシュー

1

Python 2.x、166 158

import re;def f(W,H,c,d,C):print'P3',W,H,255,re.sub('[^0-9]',' ',repr([[d,c][sum([abs(x-X+1j*(y-Y))<r for r,x,y in C])%2]for Y in range(H)for X in range(W)]))

この関数は、標準出力にPPMファイルを生成します。

例:

W = 300
H = 200
C1 = (255, 200, 0)
C2 = (128, 0, 255)
Circles = [(25, 50, 80), (40, 80, 120), (300, -100, 6), (17, 253, 162)]

f(W, H, C1, C2, Circles)

例


1

Common Lisp + Quicklisp + ZPNG 260 + 20 = 280文字

これは私がCLで書いた中で最も広いコードの一部であり、コードゴルフをしていないなら、読みやすくするためにこれを再構築したでしょう...

プレリュード(20文字)

(ql:quickload 'zpng)

ゴルフ(260文字)

(lambda(w h g b c)(make-instance'zpng:png :image-data(coerce(loop :for j :below h :nconc(loop :for i :below w :append(if(evenp(count t(mapcar(lambda(c)(<(abs(complex(-(cadr c)i)(-(caddr c)j)))(car c)))c)))g b)))'(array(unsigned-byte 8)(*))):width w :height h))

ゴルフをしていない:

(テストを可能にするためにdefunを使用し、読みやすいように長い変数名)

(defun mk-png (width height color1 color2 circles)
  (make-instance 'zpng:png
                 :image-data (coerce (loop :for j :below height
                                           :nconc (loop :for i :below width
                                                        :append (if (evenp (count t (mapcar (lambda (circ)
                                                                                              (< (abs (complex (- (cadr circ) i) (- (caddr circ) j)))
                                                                                                 (car circ)))
                                                                                            circles)))
                                                                    color1 color2)))
                                     '(array (unsigned-byte 8) (*)))
                 :width width
                 :height height))

使用例:

(let ((png (mk-png 300 200 '(255 200 0) '(128 0 255) '((25 50 80) (40 80 120) (300 -100 6) (17 253 162)))))
  (zpng:write-png png #p"path/to/file.png"))

説明

(lambda (circ)
   (< (abs (complex (- (cadr circ) i) (- (caddr circ) j)))
      (car circ)))

ポイント(i、j)が指定された円circ内にある場合、trueを返します。ユークリッド距離は、(i、j)からcircの中心までのベクトルを表す複素数の絶対値を取ることによって計算されます。

(evenp (count t (mapcar ___
                         circles)))

円のリスト全体に機能するマップを作成し、指定されたポイント(i、j)が偶数の円内にあるかどうかを確認します。

(if ____
     color1 color2)

そのテストに基づいて色を選択します。

(loop :for j :below height
       :nconc (loop :for i :below width
                    :append ____))

画像内の各(i、j)をループし、結果のリストを一緒に追加することにより、すべてのrgbバイトのフラットリストを収集します。

(coerce ____
         '(array (unsigned-byte 8) (*)))

そのバイトのリストを適切なバイトの配列に変換して、zpngが適切に取り込めるようにします。

(make-instance 'zpng:png
                :image-data ____
                :width width
                :height height)

pngオブジェクトを作成します。

(defun mk-png (width height color1 color2 circles)
   ___)

関数を作成して、幅、高さ、2つの色、円のリストを取得し、作成されたpngオブジェクトを返します。


0

JavaScript(ES6)、224バイト

私はJS + SVGソリューションを見ましたが、キャンバスベースのソリューションを作成する必要がありました;-)これはキャンバス要素を返す関数です。既存のキャンバス要素を提供できる場合は、40バイトを削除します。

のような呼び出し f(width, height, [[r1, g1, b1], [r2, g2, b2]], [[r1, x1, y1], [r2, x2, y2], ...])

let f =
(w,h,a,c,O=document.createElement`canvas`)=>{O.width=w;O.height=h;C=O.getContext`2d`;for(y=0;y<h;y++)for(x=0;x<w;x++)C.fillStyle=`rgb(${a[c.filter(([R,X,Y])=>(X-x)**2+(Y-y)**2<R**2).length%2]})`,C.fillRect(x,y,1,1);return O}

let tests = A.innerHTML.match(/.+/g);
A.innerHTML = "";
for (let i of tests) {
  let p = document.createElement("span");
  p.innerHTML = "<br>" + i.slice(0, 3);
  p.style["font-family"] = "monospace";
  A.append(p);
  A.append(f(100, 60, [[255,0,0], [0,0,255]],
    eval(`[${ i.slice(3).replace(/\(/g, "[").replace(/\)/g, "]") }]`)
  ));
}
<div id=A>
A. 
B. (13, 16, 20)
C. (30, 16, 20)
D. (200, 16, 20)
E. (42, 50, 20)
F. (42, 50, 20), (17, 40, 30)
G. (42, 50, 20), (17, 20, 30)
H. (42, 50, 20), (17, 10, 30), (10, 50, 30)
I. (42, 50, 20), (17, 10, 30), (35, 50, 20)
J. (18, 36, 40), (18, 63, 40), (18, 50, 20)
K. (100, -10, -20), (60, 50, -10)
L. (18, 36, 40), (18, 63, 40), (18, 50, 20), (14, 50, 20), (5, 50, 18), (20, 0, 0), (70, 22, 0), (10000, -9970, 0), (135, 100, -80)
</div>

出力例:

二色の円


0

Löve2D、353バイト。

o=love.graphics
a=arg
w,h,r,g,b,R,G,B=...c={}for i=9,#a,3 do
c[#c+1]={a[i],a[i+1],a[i+2]}end
C=o.newCanvas(w,h)o.setCanvas(C)o.clear(R,G,B)for k,v in pairs(c)do
o.stencil(function()o.circle("fill",v[2],v[3],v[1],9^3)end,"invert",1,true)end
o.setStencilTest("greater",0)o.setColor(r,g,b)o.rectangle("fill",0,0,w,h)local
C:newImageData():encode("png","c")
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.