Lingkaran Tumpang tindih Dua Warna

22

Tulis program atau fungsi yang menggunakan input berikut dalam format pilihan Anda yang masuk akal:

  • Dua bilangan bulat positif W dan H yang menentukan lebar dan tinggi gambar yang akan Anda hasilkan.

  • Dua warna RGB C1 dan C2 yang akan digunakan untuk mewarnai gambar.

  • Daftar 3-tupel formulir (r, x, y)yang menentukan lingkaran dengan jari-jari rdan pusat x, ydi bidang gambar. radalah bilangan bulat positif dan xdan ybilangan bulat apa saja. Pixel kiri atas gambar adalah 0, 0dan sumbu x meningkat ke kanan dan sumbu y meningkat ke bawah.

Keluarkan gambar dengan dimensi W oleh H yang diwarnai dengan C1 dan C2 sehingga tidak ada dua daerah tetangga yang ditentukan oleh semua lingkaran yang tumpang tindih dengan warna yang sama.

Misalnya: Jika inputnya adalah

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)

maka batas lingkaran terlihat seperti ini:

contoh 1 batas lingkaran

Ada enam wilayah berbeda yang bersebelahan dalam gambar yang dibuat oleh lingkaran. Setiap daerah harus diwarnai dengan C1 (kuning) atau C2 (ungu) sehingga tidak ada dua daerah tetangga yang warna yang sama.

Ada dua cara untuk melakukan ini, satu-satunya perbedaan adalah bahwa warna ditukar:

contoh 1 output 1 contoh 1 output 2

Jadi, salah satu dari kedua gambar ini akan menjadi output yang valid untuk input contoh.

Sesuatu seperti ini akan menjadi keluaran yang tidak valid karena dua daerah kuning saling bertetangga.

Gambar output Anda harus mengikuti pedoman ini:

  • Selain C1 dan C2, warna netral ketiga seperti hitam atau putih dapat digunakan untuk batas lingkaran asalkan ketebalannya tidak lebih dari 5 piksel. (Hitam, batas tebal 1-piksel ada pada contoh di atas.)

  • Batas lingkaran tidak diperlukan. Daerah-daerah dapat saling bertetangga secara langsung:

    contoh 1 output 3 contoh 1 output 4

    Kedua hal ini merupakan keluaran yang valid untuk contoh di atas.

  • Lingkaran harus seakurat mungkin, menggunakan algoritme menggambar lingkaran atau apa pun yang disediakan perpustakaan grafis Anda.

  • Secara umum, penyempurnaan piksel tidak diperlukan, tetapi jika parameter input diskalakan lebih besar dan lebih besar, gambar yang dihasilkan harus menjadi lebih dan lebih akurat.

  • Anti-aliasing diizinkan tetapi tidak diperlukan.

  • Label garis kisi atau sumbu dll di latar belakang tidak diperbolehkan.

Kode terpendek dalam byte menang.

Lebih banyak contoh

Semua menggunakan input ini dengan rangkaian lingkaran yang berbeda:

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

Dalam contoh apa pun, warna dapat ditukar dan tetap valid.

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. ex E F. ex F G. ex G H. ex H
I. ex I J. ex J K. ex K L. ex L

Pastikan output Anda berperilaku mirip dengan semua contoh ini.

Hobi Calvin
sumber
Kelihatannya bagus, bisakah kita output di ascii, misalnya C1 adalah 1 dan C2 adalah 0?
Matthew Roh
@ MatthewRoh No. Saya tahu itu akan mudah tetapi gambar diperlukan.
Calvin Hobbies
1
Baiklah kalau begitu saya rasa saya bisa berhitungtikz
Wheat Wizard
1
@MatthewRoh, netpbm adalah format gambar yang umum digunakan di situs ini.
Peter Taylor
2
@Luis Oke. Variasi input kecil seperti itu atau memiliki sumbu y naik baik-baik saja.
Calvin Hobbies

Jawaban:

14

Mathematica, 165 byte

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}]&

Fungsi murni mengambil empat argumen: lebar, tinggi (kedua bilangan bulat), sepasang tiga kali lipat angka antara 0 dan 1 (mewakili dua warna RGB), dan daftar item formulir {r, {x, y}}untuk merekam jari-jari dan pusat-pusat dari lingkaran. Misalnya, contoh pertama dalam OP akan dipanggil dengan argumen [300, 200, {{1, 0.784, 0}, {0.5, 0, 1}}, {{25, {50, 80}}, {40, {80, 120}}, {300, {-100, 6}}, {17, {253, 162}}}]. Sumbu y positif menunjuk ke atas di Mathematica.

Norm[{x,y}-#2]<#mendeteksi apakah suatu titik berada di dalam lingkaran yang diberikan; Boole[...]Pimengubah itu Trueatau Falseke πatau 0. Setelah menghitung πs / 0s pada semua lingkaran input, Trtambahkan mereka dan ubah Coskelipatan genap π menjadi 1, kelipatan ganjil π hingga –1. ContourPlot[...,Contours->{0}]kemudian warna wilayah yang sesuai dari pesawat dalam dua warna tergantung pada apakah nilainya lebih besar atau kurang dari 0. AspectRatio->Automaticmembuat lingkaran tampak seperti lingkaran; PlotPoints->5!memberikan akurasi yang layak (tingkatkan ke 9!jika Anda benar-benar menginginkan gambar yang menakjubkan, jauh di masa depan!); Frame->Falsemenghilangkan kapak; dan ContourShading->RGBColor@@@#3menggunakan warna input untuk kontur.

Output sampel, dengan pasangan warna pertama (karena bagus) tetapi rangkaian lingkaran terakhir:

output sampel

Greg Martin
sumber
11

JavaScript / SVG / HTML5, 219 byte

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>`));

Neil
sumber
10

BBC Basic, 120 117 byte

Unduh juru bahasa di 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 memiliki serangkaian mode warna yang memungkinkan Anda untuk merencanakan grafik raster sesuai dengan operasi logika dasar: OR, AND, XOR dll.

Ini juga mendukung pemrograman ulang pallete, artinya misalnya di sini gambar 2 warna dapat memprogram ulang warnanya ke 4096 warna. Implementasi yang digunakan di sini memiliki beberapa (tidak terdokumentasi) perbedaan dari implementasi BBC asli, di mana operator EOR tidak diperlukan.

Tidak disatukan

  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

Layar keluaran khas

Contoh gambar ditingkatkan dengan faktor 10 dalam satuan / faktor 5 dalam piksel (dasar BBC menggunakan 1 piksel = 2 unit.)

masukkan deskripsi gambar di sini

Level River St
sumber
10

MATL , 30 29 25 byte

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

Masukkan format:

  • Colormap sebagai matriks nilai antara 0 dan 255, di mana setiap baris mendefinisikan warna
  • W
  • H
  • Vektor kolom koordinat pusat berbasis 1 sebagai nilai kompleks ( x adalah bagian nyata, y adalah bagian imajiner)
  • Vektor kolom jari-jari.

Coba di MATL Online! Atau verifikasi kasus uji terakhir . (Penerjemah masih eksperimental. Anda mungkin perlu menyegarkan halaman dan coba lagi jika tidak berhasil).

Penjelasan

Kode ini menggunakan bilangan kompleks untuk menentukan kisi poin dan menghitung jarak, dan menggunakan operasi array dengan penyiaran .

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
Luis Mendo
sumber
2
Saya katakan Simpan Itu Bytes! : D
Greg Martin
1
@GregMartin Anda benar. Siapa yang peduli tentang keanggunan ketika 4 byte bisa diselamatkan! :-) Selesai
Luis Mendo
1
@LuisMendo Semakin pendek semakin baik dengan codegolf, betapapun jeleknya itu. ;)
Kevin Cruijssen
6

Python menggunakan pypng , 140 138 byte

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')

Contoh penggunaan:

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')

Terima kasih kepada xnor karena telah menghemat 2 byte.

Alex Hall
sumber
Selamat datang di kode golf! Untuk memeriksa apakah titik terletak pada lingkaran, satu trik adalah dengan menggunakan norma kompleks: abs(x-X+1j*(y-Y))<r.
xnor
3

Matematika (tidak bersaing)

(idk bagaimana melakukan LaTeX di PPCG, jadi saya menggunakan alat LaTeX untuk png)

Penjelasan

Produk dari beberapa persamaan lingkaran ( (x-a)^2+(y-b)^2-r^2)> = 0 akan membuat grafik yang dibutuhkan pertanyaan ini. Dalam persamaan, nadalah ukuran array, dan (x, y or r)_kmerupakan elemen kth (x, y, or r).

Contoh

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

(Terima kasih WolframAlpha)

(Plot ketidaksetaraan oleh WolframAlpha)

Dapatkan / Jalankan persamaan untuk WolframAlpha

Mendapatkan skrip: Lengkap

Running script: Belum selesai

Sekarang buat itu bekerja dengan Mathematica ...

Matthew Roh
sumber
Saya ingin tahu apakah ini valid?
Matius Roh
Anda perlu membuat daftar juru bahasa tertentu yang sudah ada sebelumnya yang akan memplot output dalam bentuk yang Anda inginkan diberi input itu. Itu akan memungkinkan untuk menghitung byte di dalamnya. Saat ini, masalahnya adalah karena itu tidak terikat pada juru bahasa, itu tidak terikat pada format tertentu untuk mewakili persamaan, dan dengan demikian notasi bersifat informal dan tidak mungkin untuk dihitung secara objektif. Ada banyak program untuk memetakan grafik persamaan di sekitar, jadi mungkin ada baiknya mencoba menemukan satu dengan format input singkat.
@ ais523 Ohh. Saya akan mencoba membuatnya bekerja dengan WolframAlpha.
Matius Roh
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)]))

Fungsi menghasilkan file PPM pada output standar.

contoh:

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)

contoh

pelaku diet
sumber
1

Gangguan Umum + Quicklisp + ZPNG 260 + 20 = 280 karakter

Ini adalah beberapa kode terluas yang pernah saya tulis dalam CL, dan jika saya tidak melakukan golf kode saya akan merestrukturisasi ini untuk membuatnya lebih mudah dibaca ...

Prelude (20 karakter)

(ql:quickload 'zpng)

Golf (260 karakter)

(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))

Tidak Disatukan:

(Menggunakan defun untuk memungkinkan pengujian dan nama variabel yang lebih panjang agar mudah dibaca)

(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))

Contoh penggunaan:

(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"))

Penjelasan

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

Mengembalikan nilai true jika titik (i, j) berada di dalam lingkaran lingkaran yang diberikan. Jarak Euclidean dihitung dengan mengambil nilai absolut dari bilangan kompleks yang mewakili vektor dari (i, j) ke pusat lingkaran.

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

Petakan fungsi itu di seluruh daftar lingkaran dan periksa apakah titik yang diberikan (i, j) termasuk dalam jumlah genap.

(if ____
     color1 color2)

Pilih warna berdasarkan tes itu.

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

Kumpulkan daftar datar semua byte rgb dengan mengulangi setiap (i, j) pada gambar dan menambahkan daftar yang dihasilkan secara bersamaan.

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

Konversikan daftar byte tersebut menjadi array byte yang tepat, sehingga zpng dapat menelannya dengan benar.

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

Buat objek png.

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

Buat fungsi untuk mengambil lebar, tinggi, dua warna, dan daftar lingkaran dan mengembalikan objek png yang dibuat.

djeis
sumber
0

JavaScript (ES6), 224 byte

Saya melihat solusi JS + SVG, tetapi saya hanya harus membuat solusi berbasis kanvas ;-) Ini adalah fungsi yang mengembalikan elemen kanvas. Jika elemen kanvas yang ada dapat disediakan, hapus 40 byte.

Sebut seperti 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>

Contoh output:

lingkaran dua warna

Produksi ETH
sumber
0

Löve2D , 353 Bytes.

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")
ATaco
sumber