Cerchi sovrapposti bicolore


22

Scrivi un programma o una funzione che accetta i seguenti input in un formato ragionevole a tua scelta:

  • Due numeri interi positivi W e H che definiscono la larghezza e l'altezza dell'immagine che genererai.

  • Due colori RGB C1 e C2 che verranno utilizzati per colorare l'immagine.

  • Un elenco di 3 tuple della forma (r, x, y)che definiscono i cerchi con raggio re centro x, ynel piano dell'immagine. rè un numero intero positivo xe ysono numeri interi. Il pixel in alto a sinistra dell'immagine è 0, 0e l'asse x aumenta a destra e l'asse y aumenta verso il basso.

Stampa un'immagine con dimensioni W di H colorata con C1 e C2 in modo tale che nessuna delle due regioni vicine definite da tutti i cerchi sovrapposti abbiano lo stesso colore.

Ad esempio: se l'ingresso è

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)

quindi i confini del cerchio si presentano così:

confini del cerchio esempio 1

Vi sono sei regioni distinte e contigue nell'immagine creata dai cerchi. Ogni regione deve essere colorata con C1 (giallo) o C2 (viola) in modo tale che non vi siano due regioni vicine dello stesso colore.

Ci sono due modi per farlo, la loro unica differenza è che i colori vengono scambiati:

esempio 1 uscita 1 esempio 1 uscita 2

Pertanto, una di queste due immagini sarebbe un output valido per l'input di esempio.

Qualcosa di simile a questo sarebbe uscita valido in quanto due regioni giallo vicino l'un l'altro.

Le immagini di output devono seguire queste linee guida:

  • Oltre a C1 e C2, un terzo colore neutro come il bianco o il nero può essere usato per i confini del cerchio purché non siano spessi più di 5 pixel. (Nell'esempio sopra sono presenti bordi neri spessi 1 pixel.)

  • I confini delle cerchie non sono richiesti, tuttavia. Le regioni possono confinarsi direttamente tra loro:

    esempio 1 uscita 3 esempio 1 uscita 4

    Entrambi questi sono un altro risultato valido nell'esempio sopra.

  • I cerchi dovrebbero essere il più precisi possibile, usando gli algoritmi di disegno del cerchio o qualsiasi altra cosa fornita dalla tua libreria grafica.

  • In generale, la perfezione dei pixel non è richiesta, ma se i parametri di input vengono ridimensionati in modo uguale sempre più grande, l'immagine risultante dovrebbe diventare sempre più accurata.

  • L'antialiasing è consentito ma non necessario.

  • Griglie o etichette degli assi ecc. In background non sono consentite.

Vince il codice più breve in byte.

Altri esempi

Tutti utilizzano questi input con diversi set di cerchi:

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

In qualsiasi esempio i colori possono essere scambiati e rimanere validi.

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 io J. ex J K. ex K L. ex L

Assicurati che l'output si comporti in modo simile a tutti questi esempi.


Sembra carino, possiamo produrre in ASCII, ad esempio C1 è 1 e C2 è 0?
Matthew Roh,

@MatthewRoh No. So che sarebbe conveniente ma sono necessarie immagini.
Calvin's Hobbies

1
Ok, allora immagino di poter contaretikz
Wheat Wizard,

1
@MatthewRoh, netpbm è un formato di immagine comunemente usato su questo sito.
Peter Taylor,

2
@Luis Ok. Piccole variazioni di input come quella o con l'asse y in alto vanno bene.
Calvin's Hobbies

Risposte:


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

La funzione pura accetta quattro argomenti: la larghezza, l'altezza (entrambi i numeri interi), una coppia ordinata di triple di numeri compresi tra 0 e 1 (che rappresentano i due colori RGB) e un elenco di elementi del modulo {r, {x, y}}per registrare i raggi e i centri di i cerchi. Ad esempio, il primo esempio nell'OP verrebbe chiamato con gli argomenti [300, 200, {{1, 0.784, 0}, {0.5, 0, 1}}, {{25, {50, 80}}, {40, {80, 120}}, {300, {-100, 6}}, {17, {253, 162}}}]. L'asse y positivo punta verso l'alto in Mathematica.

Norm[{x,y}-#2]<#rileva se un punto si trova all'interno di un determinato cerchio; Boole[...]Piconverte quello Trueo Falsein πo 0. Dopo aver calcolato quei π / 0 su tutti i cerchi di input, Trli somma e Cosconverte i multipli pari di π in 1, multipli dispari di π in -1. ContourPlot[...,Contours->{0}]quindi colora la regione appropriata del piano in due colori a seconda che il valore sia maggiore o minore di 0. AspectRatio->Automaticfa apparire i cerchi come cerchi; PlotPoints->5!dà una precisione decente (aumentala 9!se vuoi davvero un'immagine straordinaria, lontano in futuro!); Frame->Falsesi libera degli assi; e ContourShading->RGBColor@@@#3utilizza i colori di input per i contorni.

Esempio di output, con la prima coppia di colori (dato che sono belli) ma l'ultimo set di cerchi:

uscita campione


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


10

BBC Basic, 120 117 byte

Scarica l'interprete su 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 ha una gamma di modalità colore che ti consentono di tracciare la grafica raster in base alle operazioni logiche di base: OR, AND, XOR ecc.

Supporta anche la riprogrammazione pallete, il che significa che ad esempio qui un'immagine a 2 colori può riprogrammare i suoi colori su uno qualsiasi dei 4096 colori. L'implementazione utilizzata qui presenta alcune differenze (non documentate) rispetto all'implementazione originale della BBC, in cui gli operatori EOR non sarebbero necessari.

Ungolfed

  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

Schermata di output tipica

Immagine di esempio ingrandita di un fattore 10 in unità / fattore 5 in pixel (BBC Basic utilizza 1 pixel = 2 unità).

inserisci qui la descrizione dell'immagine


10

MATL , 30 29 25 byte

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

Formato di input:

  • Mappa dei colori come matrice di valori tra 0 e 255, in cui ogni riga definisce un colore
  • W
  • H
  • Vettore di colonna di coordinate centrali basate su 1 come valori complessi ( x è la parte reale, y è la parte immaginaria)
  • Vettore di colonna di raggi.

Prova su MATL Online! Oppure verifica l'ultimo caso di test . (L'interprete è ancora sperimentale. Potrebbe essere necessario aggiornare la pagina e riprovare se non funziona).

Spiegazione

Il codice utilizza numeri complessi per definire la griglia di punti e calcolare le distanze e fa un uso pesante delle operazioni di array con la trasmissione .

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
Dico Salva quei byte! : D
Greg Martin

1
@GregMartin Hai ragione. Chi se ne frega dell'eleganza quando è possibile salvare 4 byte! :-) Fatto
Luis Mendo,

1
@LuisMendo Più corto è meglio con codegolf, non importa quanto brutto diventi. ;)
Kevin Cruijssen,

6

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

Esempio di utilizzo:

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

Grazie a xnor per aver salvato 2 byte.


Benvenuto in codice golf! Per verificare se un punto giace in un cerchio, un trucco è quello di utilizzare norma complessa: abs(x-X+1j*(y-Y))<r.
xnor

3

Matematica (non competitiva)

(idk come fare LaTeX in PPCG, quindi ho usato uno strumento LaTeX per png)

Spiegazione

Il prodotto delle equazioni multiple del cerchio ( (x-a)^2+(y-b)^2-r^2)> = 0 farà un grafico di cui ha bisogno questa domanda. Nell'equazione, nè la dimensione dell'array ed (x, y or r)_kè l' elemento kth (x, y, or r).

Esempio

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

(Grazie WolframAlpha)

(Disuguaglianza di WolframAlpha)

Ottieni / esegui equazione per WolframAlpha

Ottenere lo script: completo

Script in esecuzione: non ancora fatto

Ora fallo funzionare con Mathematica ...


Mi chiedo se questo è valido?
Matthew Roh,

Dovresti elencare uno specifico interprete preesistente che traccia il risultato nella forma desiderata, dato quel dato. Ciò consentirebbe di contare i byte al suo interno. Allo stato attuale, il problema è che, poiché non è legato a un interprete, non è legato a un formato specifico per rappresentare l'equazione, e quindi la notazione è informale e impossibile da contare obiettivamente. Esistono molti programmi per tracciare grafici di equazioni in giro, quindi potrebbe valere la pena provare a trovarne uno con un formato di input conciso.

@ ais523 Ohh. Proverò a farlo funzionare con WolframAlpha.
Matthew 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)]))

La funzione genera un file PPM sull'output standard.

esempio:

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)

esempio


1

Lisp comune + Quicklisp + ZPNG 260 + 20 = 280 caratteri

Questo è uno dei codici più ampi che abbia mai scritto in CL, e se non stessi facendo un codice golf lo avrei ristrutturato per rendere molto più facile la lettura ...

Preludio (20 caratteri)

(ql:quickload 'zpng)

Golfato (260 caratteri)

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

Ungolfed:

(Utilizza defun per consentire test e nomi di variabili più lunghi per la leggibilità)

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

Esempio di utilizzo:

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

spiegazione

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

Restituisce vero se il punto (i, j) rientra nel circolo dato. La distanza euclidea viene calcolata prendendo il valore assoluto del numero complesso che rappresenta il vettore da (i, j) al centro del circ.

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

Mappa che funzionano attraverso l'elenco delle cerchie e controlla se il dato punto (i, j) rientra in un numero pari di cerchie.

(if ____
     color1 color2)

Seleziona il colore in base a quel test.

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

Raccogli insieme un elenco semplice di tutti i byte rgb eseguendo il ciclo su ciascuno (i, j) nell'immagine e accodando gli elenchi risultanti insieme.

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

Converti quell'elenco di byte in un array di byte adeguato, in modo che zpng possa ingerirlo correttamente.

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

Crea l'oggetto png.

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

Crea la funzione per prendere la larghezza, l'altezza, due colori e l'elenco dei cerchi e restituire l'oggetto png creato.


0

JavaScript (ES6), 224 byte

Ho visto la soluzione JS + SVG, ma dovevo solo creare una soluzione basata su tela ;-) Questa è una funzione che restituisce un elemento tela. Se è possibile fornire un elemento canvas esistente, rimuovere 40 byte.

Chiama come 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>

Esempio di output:

cerchi bicolori


0

Löve2D , 353 byte.

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")
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.