Programme de dessin court


13

Vous venez d'inviter un majeur des arts libéraux chez vous et vous lui dites

"Vous savez, je suis un excellent programmeur et je peux faire x et y et z ..."

Il s'ennuie rapidement et vous demande:

"Si vous êtes vraiment un grand programmeur, pouvez-vous créer un programme pour me permettre de dessiner, j'ai juste besoin de tracer des lignes sur l'écran en utilisant la souris et en sélectionnant différentes couleurs de n'importe quelle manière".

Votre code peut importer des bibliothèques standard. Votre code peut exiger que les couleurs soient sélectionnées via le clavier.

C'est du ; le code le plus court gagne.

Points de balle

  • Les lignes sont dessinées en déplaçant la souris tout en appuyant sur le bouton gauche.

  • L'algorithme de ligne de Bresenham n'est pas nécessaire, aucun algorithme intégré ne fera l'affaire

  • Si l'utilisateur peut modifier l'épaisseur de la ligne de quelque manière que ce soit, vous obtenez un bonus de * 0.8 mais ce n'est pas obligatoire.

  • Je suppose que cela devrait être plus agréable d'implémenter le dessin au trait nous-mêmes, mais si vous le souhaitez, vous pouvez importer une bibliothèque pour cela, dites-le simplement dans la description du code.

  • Le minimum est de 5 couleurs différentes (rouge, vert, bleu, blanc, noir). Si vous les faites changer au hasard, vous obtenez une pénalité de * 1,2. Vous pouvez les modifier comme vous le souhaitez (les touches et les touches sont OK).

  • Les dessiner en appuyant sur la souris entre des points ou à main levée serait le meilleur (c'est-à-dire comme vous le faites dans la peinture) et vous donne un bonus de * 0.7, mais toute autre méthode est correcte: (exemple) cliquez sur deux points et tracez une ligne entre ces points ?

  • La toile de dessin doit être de 600x400

  • Changer la couleur ne devrait changer que la couleur des lignes qui seront tracées à l'avenir.

  • L'implémentation d'une commande "Clear All" n'est pas obligatoire mais si vous l'implémentez, vous obtenez un bonus de * 0.9 .


2
Comment faut-il tracer les lignes? L'algorithme de ligne de Bresenham ? Les lignes doivent-elles être d'épaisseur variable? Avons-nous besoin de mettre en œuvre le dessin au trait nous-mêmes? Veuillez préciser davantage. Et il est normalement supposé que notre code peut "importer des bibliothèques standard". Combien de couleurs faut-il choisir? Est-ce que 2 va bien? Ou que diriez-vous de choisir au hasard une couleur à chaque fois que vous appuyez sur un bouton du clavier?
Justin

2
Quelques précisions supplémentaires sont nécessaires: Comment sont tracées les lignes? Cliquez-vous sur deux points et tracez une ligne entre ces points? Quelle doit être la taille de la toile de dessin? Combien de couleurs doivent être prises en charge? Le changement de couleur peut-il également changer la couleur de toutes les autres lignes? Etc. Ce défi est actuellement très peu spécifié.
Poignée de porte

@Quincunx J'ai mis un Q & A dans la question, dites-moi si ça va maintenant.
Caridorc

2
1. Veuillez condenser les questions et réponses. Éliminez les questions et faites en sorte que les réponses se présentent comme des puces. Notez que les commentaires peuvent parfois être supprimés. Le point d'algorithme de Bresenham n'a aucun sens sans lire le commentaire. Je suppose que ce que vous dites est que l'algorithme de Bresenham n'est pas requis et que n'importe quel algorithme ou fonction standard / bibliothèque fera l'affaire. 2. En fin de compte, gagner dépend de la langue dans laquelle il est facile d'accéder à l'API et d'accéder au bouton droit (au lieu du bouton gauche habituel).
Level River St

2
1. "Les dessiner en appuyant sur la souris entre 2 points est préférable mais toute autre méthode est ok" Qu'en est-il du dessin à main levée comme avec l'outil crayon dans la peinture? Je vous suggère de le rendre plus clair ou d'éliminer complètement «toute autre méthode est acceptable». 2. La méthode de changement de couleur devrait être mieux spécifiée. Par exemple, cela peut-il être fait à partir du clavier, en faisant défiler les couleurs avec l'autre bouton de la souris, ou faut-il le faire en cliquant sur une palette à l'écran?
Level River St

Réponses:


9

HTML + jQuery + CSS - 507 x (0,7 x 0,8 x 0,9) = 255,528

Pas aussi court que je le pensais, mais j'aime le résultat.

Fonctionnalités:

  • Cliquez et faites glisser le mode de dessin. ( 0,7 )
  • Sept couleurs (noir + arc-en-ciel).
  • Largeur de brosse variable (contrôle du curseur). ( 0,8 )
  • Effacer toutes les fonctions. ( 0,9 )

Démo en direct: http://jsfiddle.net/onsLkh8y/9/


HTML - 84 octets

<input id="r" type="range" min="1" max="9"><canvas id="c" width="600" height="400"/>

CSS - 35 octets

#c{border:1px solid;cursor:pointer}

jQuery - 388/446 octets

Navigateurs compatibles W3C (par exemple Chrome) - 388 octets

var t=c.getContext('2d');$.each('black0red0orange0yellow0green0blue0purple0clear'.split(0),function(k,v){
$(r).before($('<button>'+v+'</button>').click(function(){k>6?t.clearRect(0,0,600,400):t.strokeStyle=v}))})
$(c).mousedown(function(e){t.lineWidth=$(r).val();t.beginPath();t.moveTo(e.offsetX,e.offsetY)})
.mousemove(function(e){if(e.which==1){t.lineTo(e.offsetX,e.offsetY);t.stroke()}})

Version Cross-Browser (correctifs pour Firefox, Safari, IE) - 446 octets

var t=c.getContext('2d');$.each('black0red0orange0yellow0green0blue0purple0clear'.split(0),function(k,v){
$(r).before($('<button>'+v+'</button>').click(function(){k>6?t.clearRect(0,0,600,400):t.strokeStyle=v}))})
var d,p=$(c).offset();$(c).mousedown(function(e){d=t.lineWidth=$(r).val();t.beginPath()t.moveTo(e.pageX-p.left,
e.pageY-p.top)}).mousemove(function(e){if(d){t.lineTo(e.pageX-p.left,e.pageY-p.top);t.stroke()}}).mouseup(function(){d=0})

Correctifs:

  • FireFox - ne event.offset[X|Y]sont pas définis.
  • Safari - event.whichet event.buttonsne sont pas définis de manière significative sur mousemove.
  • Internet Explorer - fonctionne avec les deux correctifs ci-dessus, bien que l'utilisation e.buttonsaurait été suffisante.

1
$ (document). déjà dans codegolf?
edc65

vous n'avez pas besoin des devis id=et peut-être d'autres aussi (vous n'avez pas fait de
code

10

Traitement - 93 · 0,9 = 83,7

Avec presque aucun frais généraux pour le dessin, mais une syntaxe très verbeuse, dans le traitement, le meilleur score est probablement atteint sans aucune fonctionnalité intéressante et un seul bonus:

void setup(){
size(600,400);
}
void draw(){
if(mousePressed)line(mouseX,mouseY,pmouseX,pmouseY);
}

Résultat: 93 · 0,9 = 83,7 (les sauts de ligne sont uniquement pour la lisibilité et ne sont pas comptés dans la partition.)

Cependant, c'est beaucoup plus amusant avec tous les bonus en place:

void setup(){
size(600,400);
}
int i,x,y;
void draw(){
stroke(7*i%256,5*i%256,i%256);
strokeWeight(i%9);
if(keyPressed)i++;
if(!mousePressed){x=mouseX;y=mouseY;if(x<0)background(0);}
}
void mouseReleased(){
line(x,y,mouseX,mouseY);
}

But: 221 · 0,8 · 0,7 · 0,9 = 111,4

Il est utilisé comme ceci:

  • Cliquez et faites glisser la souris pour tracer une ligne droite.

  • Lorsque vous cliquez dessus, faites glisser la souris hors du côté gauche de la fenêtre et relâchez le bouton de la souris pour effacer l'écran.

  • Maintenir une touche enfoncée fait défiler les valeurs rouge, verte et bleue de la couleur du dessin et les différentes épaisseurs de trait. Étant donné que les périodes de cyclisme sont différentes, pratiquement toutes les combinaisons peuvent être atteintes (avec un peu d'essais).

sortie colorée 1

Éditer:

Étant donné que le dessin à main levée donne également le bonus de 0,7, voici une autre solution:

void setup(){
size(600,400);
}
int i;
void draw(){
stroke(7*i%256,5*i%256,i%256);
strokeWeight(i%9);
if(keyPressed)i++;
if(key>9)background(0);
if(mousePressed)line(mouseX,mouseY,pmouseX,pmouseY);
}

But: 188 · 0,8 · 0,7 · 0,9 = 94,8

Il est utilisé comme ceci:

  • Cliquez et faites glisser pour dessiner des lignes à main levée.

  • Maintenez la touche de tabulation pour modifier la couleur et l'épaisseur du trait. Cela peut également être fait pendant le dessin (voir photo).

  • Appuyez sur n'importe quelle touche mais sur l'onglet puis sur l'onglet pour effacer l'écran.

sortie colorée 2


Freehand vous donne également le bonus.
Caridorc

@Caridorc: Ah, super. Je mettrai alors à jour ma réponse.
Emil

2
Ça va être difficile à battre.
primo

if(key>0) est plus court que if(keyPressed)
user41805

9

Python 2,7 - 339 197 324 * (0,7 * 0,8 * 0,9) = 163

Edit: j'ai découvert que pygame peut dessiner des lignes avec une largeur variable alors voici une mise à jour.

Une expérience d'utilisation des modules PyGame.

Un programme de peinture simple qui trace des lignes de l'événement MOUSEDOWN (valeur 5) à l'événement MOUSEUP (valeur 6). Il utilise la fonction pygame.gfxdraw.line (). Appuyez sur la touche TAB pour parcourir 8 couleurs. Appuyez sur la touche RETOUR ARRIÈRE pour effacer l'affichage d'une couleur de papier blanc soigneusement conçue. La touche ENTER fait défiler la taille du pinceau sur une largeur de 0 à 7 pixels.

Je suis nouveau au code-golf, donc j'ai peut-être manqué certaines méthodes de réduction de la taille du code.

import pygame as A,pygame.draw as G
P=A.display
D=P.set_mode((600,400))
C=(0,255)
S=[(r,g,b) for r in C for g in C for b in C]
w=n=1
while n:
 e=A.event.wait()
 t=e.type
 if t==12:n=0
 if t==2:
  if e.key==9:n+=1
  if e.key==13:w+=1
  if e.key==8:D.fill(S[7])
 if t==5:p=e.pos
 if t==6:G.line(D,S[n%8],p,e.pos,w%8)
 P.flip()

Exemple d'image 1:

Terrible photo d'un avion

Exemple d'image 2:

Paysage


9
J'ai maintenant un fichier sur mon ordinateur nommé ms-paint.py.
primo

1
Profitez de la vitesse et d'une interface graphique claire. Comment MS-Paint devait être. J'espère que je ne serai pas poursuivi par une grande société de logiciels ...
Logic Knight

5

C # 519 x 0,7 x 0,8 x 0,9 = 261,6 en utilisant la méthode DrawLine.

Golfé:

using System;using System.Drawing;using System.Windows.Forms;class f:Form{[STAThread]static void Main(){f F=new f{Width=600,Height=400};Point s=default(Point);sbyte[]c={0,0,0,1};F.MouseDown+=(_,e)=>{s=new Point(e.X,e.Y);};F.MouseUp+=(_,e)=>{F.CreateGraphics().DrawLine(new Pen(Color.FromArgb(255,c[0],c[1],c[2]),c[3]),s.X,s.Y,e.X,e.Y);};F.KeyPress+=(a,e)=>{unchecked{switch(e.KeyChar){case'r':c[0]++;break;case'g':c[1]++;break;case'b':c[2]++;break;case't':c[3]++;break;case'c':F.Invalidate();break;}}};F.ShowDialog();}}

Lisible:

using System;
using System.Drawing;
using System.Windows.Forms;

class f : Form
{
    [STAThread]
    static void Main()
    {
        f F = new f { Width = 600, Height = 400 };
        Point s = default(Point);
        sbyte[] c = { 0, 0, 0, 1 };
        F.MouseDown += (_, e) => { s = new Point(e.X, e.Y); };
        F.MouseUp += (_, e) => { F.CreateGraphics().DrawLine(new Pen(Color.FromArgb(255, c[0], c[1], c[2]), c[3]), s.X, s.Y, e.X, e.Y); };
        F.KeyPress += (a, e) =>
        {
            unchecked
            {
                switch (e.KeyChar)
                {
                    case 'r': c[0]++; break;
                    case 'g': c[1]++; break;
                    case 'b': c[2]++; break;
                    case 't': c[3]++; break;
                    case 'c': F.Invalidate();break;
                }

            }
        };
        F.ShowDialog();
    }
}

En maintenant r , g ou b sur votre clavier, cela change la couleur de la ligne suivante en incrémentant un sbyte-array à l'index correspondant. Il recommencera à 0 en cas de débordement. Cela nous donne donc beaucoup de couleurs. Il en va de même pour l'épaisseur de la ligne qui est augmentée en maintenant t . Appuyez sur c pour effacer le formulaire.


5

Mathematica - 333 x 0,7 x 0,8 x 0,9 = 168

l = {}; c = Black; s = .01;
ColorSetter@Dynamic@c
Dynamic@s~Slider~{0, .02}
Button["Clear", l = {}]
"/" Checkbox@Dynamic@b
EventHandler[
 Dynamic@Graphics@{White, Rectangle@{600, 400}, l},
 {"MouseDown" :> 
   AppendTo[l, p = {}; {c, Thickness@s, Line@Dynamic@p}], 
  "MouseDragged" :> (p = 
     Append[p, MousePosition@"Graphics"][[If[b, {1, -1}, All]]]),
  "MouseUp" :> (l[[-1, 3]] = Line@p)
  }
 ]

entrez la description de l'image ici


Cela peut-il tracer des lignes d'un point à un autre? Il semble autoriser uniquement le dessin à main levée.
trichoplax

@githubphagocyte Ouais, main libre seulement pour le moment.
swish

1
@githubphagocyte Ajout d'une option de ligne droite
swish

meilleure réponse jusqu'à présent.
primo

J'adore le dessin cependant.
tomsmeding

4

Tcl / Tk, 252

x 0,8 x 0,7 x 0,9

= 127 008

253 x 0,8 x 0,7 x 0,9 = 127 512

254 x 0,8 x 0,7 x 0,9 = 128 016

255 x 0,8 x 0,7 x 0,9 = 128,52

grid [canvas .c -w 600 -he 400]
set c red
incr t
lmap k {1
B1-Motion
3
MouseWheel
2} s {{set L [.c cr l %x %y %x %y -f $c -w $t]}
{.c coo $L "[.c coo $L] %x %y"}
{set c [tk_chooseColor]}
{if $t|%D>0 {incr t [expr %D/120]}}
{.c de all}} {bind . <$k> $s}

Tcl / Tk, 267

x 0,8 x 0,7 x 0,9

= 134,568

grid [canvas .c -w 600 -he 400]
set c red
set t 0
bind .c <1> {set L [.c cr l %x %y %x %y -f $c -w $t]}
bind .c <B1-Motion> {.c coo $L "[.c coo $L] %x %y"}
bind .c <3> {set c [tk_chooseColor]}
bind .c <MouseWheel> {if $t||%D>0 {incr t [expr %D/120]}}
bind .c <2> {.c de all}

Pour l'utiliser:

  • Le bouton gauche de la souris se comporte comme des demandes de questions
  • La couleur initiale est rouge. La souris droite affiche une boîte de dialogue qui permet à l'utilisateur de choisir la couleur qui sera utilisée la prochaine fois. Appuyez toujours sur le bouton OK, sinon la couleur ne sera pas définie. Je pourrais résoudre ce problème, mais cela consommerait des octets
  • Pour ajuster l'épaisseur de la ligne qui sera utilisée la prochaine fois, vous pouvez tourner la molette de la souris: Haut = plus épais, Bas = plus fin
  • Pour effacer l'image, appuyez sur le bouton central de la souris

Un test simple:

entrez la description de l'image ici


2

DarkBASIC Pro - 318 x 0,7 x 0,9 = 200,34

La chose la plus intéressante ici est d'utiliser une logique au niveau du bit sur le scancode du clavier actuel pour changer la couleur. J'utilise deux bits différents du scancode pour chaque canal - donc presque toutes les couleurs 6 bits sont possibles.

  • Maintenez n'importe quelle touche de votre clavier pour utiliser une couleur (sur mon clavier américain: blanc = F5, noir = pas de touche, rouge = 2, vert = - (moins), bleu = b)
  • Clic droit pour effacer

Voici un EXE compilé: Télécharger

#constant a set current bitmap
set display mode 800,400,32
create bitmap 1,800,400
do
s=scancode()
ink rgb((s&&3)*85,((s/4)&&3)*85,((s>>4)&&3)*85),0
m=mousex()
n=mousey()
o=mouseclick()
if o*(d=0) then d=1:x=m:y=n
a 1
if (o=0)*d then d=0:line x,y,m,n
if o=2 then cls
a 0
cls
copy bitmap 1,0
if d then line x,y,m,n
loop

1

BBC BASIC - 141 pas de bonus

Mon premier langage de programmation et généralement plus utilisé par moi :)

SYS "SetWindowPos",@hwnd%,0,0,0,600,400,6:VDU 26
1 MOUSE X,Y,b
IF b=4 THEN GOTO 4
GOTO 1
4 MOUSE x,y,b
IF b=0 THEN LINE X,Y,x,y:GOTO 1
GOTO 4

1

Python 2.7 - 384 * .8 * .7 = 215.04

from Tkinter import*;o=1
a='0f';C=['#'+r+g+b for r in a for g in a for b in a]
def i(a):global o;o+=1
def d(a):global o;o-=1
def I(a):global u;u+=1
def D(a):global u;u-=1
m=Tk();u=0;c=Canvas(width=600,height=400);c.bind("<B1-Motion>",lambda x:c.create_rectangle((x.x,x.y,x.x+o,x.y+o),fill=C[u],outline=C[u]));m.bind("q",i);m.bind("w",d);m.bind("x",D);m.bind("z",I);c.pack();mainloop()

Avec tous les bonus: 462 * .9 * .8 * .7 = 232.848

from Tkinter import*;o=1
a='0f';C=['#'+r+g+b for r in a for g in a for b in a]
def i(a):global o;o+=1
def d(a):global o;o-=1
def I(a):global u;u+=1
def D(a):global u;u-=1
m=Tk();u=0;c=Canvas(width=600,height=400);c.bind("<B1-Motion>",lambda x:c.create_rectangle((x.x,x.y,x.x+o,x.y+o),fill=C[u],outline=C[u]));m.bind("q",i);m.bind("w",d);m.bind("x",D);m.bind("z",I);m.bind("m",lambda _:c.create_rectangle((0,0,602,402),fill=C[7],outline=C[5]));c.pack();mainloop()
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.