Grafische Darstellung von Koch Snowflake

13

Eine Koch-Schneeflocke generieren

Eine Koch-Schneeflocke ist ein Dreieck, nin dessen Mitte jeweils ein weiterer gleichseitiger Punkt eingefügt wird: http://en.wikipedia.org/wiki/Koch_snowflake#Properties

Wir hatten bereits eine Koch Snowflake Herausforderung für n=4. Die neue Herausforderung besteht darin, eine Kochschneeflocke nzwischen 1und zu zeichnen 10.

Regeln

Die Schneeflocken sind möglicherweise nicht im Programm oder in Dateien fest codiert - sie müssen von Ihrem Programm generiert werden.

Ihr Programm muss alle Größen nzwischen 1 und 10 unterstützen.

Die Anzahl der Seiten muss vom Benutzer über die Standardeingabe eingegeben werden.

Sie müssen eine grafische Darstellung der Schneeflocke auf dem Bildschirm drucken.

Probieren Sie Koch-Schneeflocken mit den nWerten 1, 2, 3 und 4 aus (grüne Linien nur zur Verdeutlichung, reproduzieren Sie sie nicht):

Koch Schneeflocken

Bei einem Tie-Break gewinnt das Programm mit der höchsten Anzahl von Upvotes (Pop-Contest).

Gemeinschaft
quelle
Ich verstehe das nicht: "Sie müssen eine Funktion verwenden, um zu berechnen, wo das Pixel platziert werden soll. Wenn Ihr Programm zu diesem Zweck keine integrierte Funktion hat, können Sie die Kosten für die Implementierung von Ihrer Punktzahl abziehen. " Welches Pixel?
Xnor
@xnor Ursprünglich sollte berechnet werden, wie die Schneeflocke auf Pixel- / Zeichenbasis gezeichnet wird (die Herausforderung war ursprünglich auch eine ASCII-Kunst-Herausforderung). Die meisten Leute werden wahrscheinlich nur Linien verwenden, also werde ich das entfernen.
Kann man die ganze Schneeflocke ausmalen?
Xnor
Natürlich. Dieser Kommentar muss länger sein.
Darüber hinaus n=7können Sie die neu hinzugefügten Dreiecke in der Schneeflocke auf einem Computerbildschirm nicht sehen. Ist hier alles in Ordnung? Gibt es eine Mindestauflösung für pixelbasierte Lösungen?
Xnor

Antworten:

7

Mathematica 72

Region@Line@AnglePath[Nest[Join@@({#,1,4,1}&/@#)&,{4,4,4},Input[]-1]π/3]

n = 3

Bildbeschreibung hier eingeben

Danke für Alephalpha.

Chyanog
quelle
Gut gemacht. Golfen Sie mit zwei Charakteren und gewinnen Sie!
@ Hosch250 Aktualisiert, Danke.
Chyanog
Sie können AnglePathin Mathematica 10.1 verwenden.
Alephalpha
@chyaongGraphics@Line@AnglePath[Nest[Join@@({-1,2,-1,#}&/@#)&,{2,2,2},Input[]-1]Pi/3]
alephalpha
1
@alephalpha 73 Zeichen:ListLinePlot@AnglePath[Nest[Join@@({#,1,4,1}&/@#)&,{4,4,4},Input[]-1]π/3]
Chyanog
15

MATLAB, 119, 115

In einer ungewöhnlichen Wendung stellte ich fest, dass dieses Programm tatsächlich besser funktionierte, als ich es spielte. Erstens wurde es aufgrund der Vektorisierung viel schneller. Jetzt wird eine hilfreiche Eingabeaufforderung angezeigt, ~n:~die den Benutzer daran erinnert, welche Menge eingegeben werden muss!

Newlines sind nicht Teil des Programms.

x=exp(i*pi/3);
o='~n:~';
P=x.^o;
for l=2:input(o);
P=[kron(P(1:end-1),~~o)+kron(diff(P)/3,[0 1 1+1/x 2]) 1];
end;
plot(P)

n = 9: n = 9

oist eine willkürliche Zeichenkette, die gleich [0 2 4 0]Modulo 6 ist. e iπ / 3, erhöht auf diese Potenzen, ergibt die Eckpunkte eines gleichseitigen Dreiecks in der komplexen Ebene. Die erste kronwird verwendet, um eine Kopie der Punkteliste zu erstellen, wobei jede 4-mal dupliziert wird. ~~oist der bequeme Weg, um einen Vektor von 4 zu erhalten. Zweitens diff(P)findet der Vektor zwischen jedem Paar aufeinanderfolgender Punkte. Zu jedem der alten Punkte werden Vielfache dieses Vektors (0, 1/3, (1 + e -iπ / 3 ) / 3 und 2/3) addiert.

Feersum
quelle
Könnten Sie uns etwas näher erläutern, wie dieser Code funktioniert? Ich dachte, ich kenne Matlab, aber das ist ... Wahnsinn? =)
Fehler
@flawr Ich habe ein paar Notizen hinzugefügt. Hilft das irgendjemandem?
Feersum
Vielen Dank! Ich werde diesen Trick des
Saitenmissbrauchs
9

T-SQL: 686 (ohne Formatierung)

Für SQL Server 2012+.

Auch wenn dies niemals ein Konkurrent sein wird, musste ich sehen, ob ich es in T-SQL schaffen konnte. Der Ansatz, mit den drei Anfangskanten zu beginnen, dann durch jede Kante zu rekursieren und sie für jedes Level durch 4 Kanten zu ersetzen, ist vorüber. Zum Schluss wird alles in einer einzigen Geometrie für die Ebene zusammengefasst, die für @i angegeben wurde

DECLARE @i INT=8,@ FLOAT=0,@l FLOAT=9;
WITH R AS(
    SELECT sX,sY,eX,eY,@l l,B,1i
    FROM(VALUES(@,@,@l,@,0),(@l,@,@l/2,SQRT(@l*@l-(@l/2)*(@l/2)),-120),(@l/2,SQRT(@l*@l-(@l/2)*(@l/2)),@,@,-240))a(sX,sY,eX,eY,B)
    UNION ALL
    SELECT a.sX,a.sY,a.eX,a.eY,l/3,a.B,i+1
    FROM R 
        CROSS APPLY(VALUES(sX,sY,sX+(eX-sX)/3,sY+(eY-sY)/3,sX+((eX-sX)/3)*2,sY+((eY-sY)/3)*2))x(x1,y1,x2,y2,x3,y3)
        CROSS APPLY(VALUES(x2+((l/3)*SIN(RADIANS(B-210.))),y2+((l/3)*COS(RADIANS(B-210.)))))n(x4,y4)
        CROSS APPLY(VALUES(x1,y1,x2,y2,B),
            (x3,y3,eX,eY,B),
            (x2,y2,x4,y4,B+60),
            (x4,y4,x3,y3,B-60)
        )a(sX,sY,eX,eY,B)
WHERE @i>i)
SELECT Geometry::UnionAggregate(Geometry::Parse(CONCAT('LINESTRING(',sX,' ',sY,',',eX,' ',eY,')')))
FROM R 
WHERE i=@i

Bildbeschreibung hier eingeben Bildbeschreibung hier eingeben

MickyT
quelle
Ich hatte keine Ahnung, dass solch eine Zauberei mit T-SQL erreicht werden kann!
Harry Mustoe-Playfair
9

LOGO: 95

to w:c ifelse:c=1[fd 2 lt 60][w:c-1 w:c-1 lt 180 w:c-1 w:c-1]end
to k:c repeat 3[w:c rt 180]end

Definiert die Funktion kmit einem einstufigen Parameter.

Bearbeiten

In diesem Online-Editor können Sie http://www.calormen.com/jslogo/ hinzufügenk readword zur Verwendung Eingabeaufforderung , aber aus irgendeinem Grund unterstützt dieser Befehl die Standardabkürzung nicht rw.

Die folgende Lösung mit 102 Zeichen funktioniert in USBLogo mit der in der Frage angegebenen Standardeingabe. Der Code musste jedoch leicht geändert werden, da UCBLogo einen seltsamen Parser hat. Es erfordert tound endin getrennten Zeilen und Leerzeichen zu sein, bevor :es erforderlich ist, aber auf der anderen Seite :sind optional.

to w c
ifelse c=1[fd 2 lt 60][w c-1 w c-1 lt 180 w c-1 w c-1]
end
to k c
repeat 3[w c rt 180]
end
k rw
nutki
quelle
Wie läuft LOGO ab?
Beta Decay
@BetaDecay Ich habe dies verwendet: logo.twentygototen.org, aber dies war das erste, das ich gefunden habe: calormen.com/jslogo Sie können auch USBLogo
nutki
8

BBC BASIC, 179

REV 1

INPUTn
z=FNt(500,470,0,0,3^n/9)END
DEFFNt(x,y,i,j,a)
LINEx-36*a,y-21*a,x+36*a,y-a*21PLOT85,x,y+a*42IFa FORj=-1TO1FORi=-1TO1z=FNt(x+24*a*i,y+j*14*a*(i*i*3-2),i,j,-j*a/3)NEXTNEXT
=0

Nach wie vor, jedoch in Schwarzweiß, ungolfed (aber stromlinienförmig) und golfed. Kein Gewinner, obwohl auf diese Weise die Notwendigkeit einer speziellen Behandlung für n = 1 vermieden wird.

  INPUTn
        REM call function and throw return value away to z
  z=FNt(500,470,0,0,3^n/9)
  END

        REM x,y=centre of triangle. a=scale.
        REM loop variables i,j are only passed in order to make them local, not global.
  DEFFNt(x,y,i,j,a)

        REM first draw a line at the bottom of the triangle. PLOT85 then draws a filled triangle,
        REM using the specified point (top of the triangle) and the last two points visited (those used to draw the line.)
  LINEx-36*a,y-21*a,x+36*a,y-21*a
  PLOT85,x,y+42*a

        REM if the absolute magnitude of a is sufficient to be truthy, recurse to the next level.
        REM j determines if the triangle will be upright, inverted or (if j=0) infinitely small.
        REM i loops through the three triangles of each orientation, from left to right.
  IFa FORj=-1TO1 FORi=-1TO1:z=FNt(x+24*a*i,y+j*14*a*(i*i*3-2),i,j,-j*a/3):NEXT:NEXT

        REM return 0
  =0

Bildbeschreibung hier eingeben

REV 0

Laut der Antwort des OP auf @xnor sind ausgefüllte Schneeflocken in Ordnung. Diese Antwort wurde von xnors Kommentar inspiriert. Die Farben sind nur zum Spaß und um zu zeigen, wie es aufgebaut ist. Nehmen Sie ein Dreieck (in diesem Fall Magenta) und überzeichnen Sie es mit 6 Dreiecken 1/3 der Basis.

  INPUTn
  z=FNt(500,470,n,1,0,0)
  END

  DEFFNt(x,y,n,o,i,a)
  a=3^n/22
  GCOLn
  MOVEx-36*a,y-o*21*a
  MOVEx+36*a,y-o*21*a
  PLOT85,x,y+o*42*a
  IFn>1FORi=-1TO1:z=FNt(x+24*a*i,y+14*a*(i*i*3-2),n-1,-1,i,a):z=FNt(x+24*a*i,y-14*a*(i*i*3-2),n-1,1,i,a)NEXT
  =0

Bildbeschreibung hier eingeben

Level River St
quelle
1
Mir gefällt, wie es aussieht, als wären 7 von ihnen zusammengeschlossen.
@ hosch250 In der Tat scheint ich ein neues Fraktal "erfunden" zu haben, dessen Silhouette zufällig eine Koch-Schneeflocke ist, und wenn Sie den magentafarbenen Teil löschen, bleiben Ihnen 6 kleinere Koch-Schneeflocken übrig. Die Golfversion wird nur eine schlichte schwarze Silhouette sein, aber ich werde dieses Bild auch belassen.
Level River St
Schreibst du BBC Basic oder BBC BASIC? Ich greife zu Letzterem, aber ich weiß nicht, ob es stimmt ...
Beta Decay
2
@BetaDecay BASIC ist ein Backronym für den Allzweck-Standard / Symbolic Instruction Code für Anfänger. Das "Standard" -Bit ist fraglich, da es so viele Varianten gibt. en.wikipedia.org/wiki/BASIC . Die meisten Varianten von BASIC bevorzugen die großgeschriebene Version, aber laut Wikipedia-Seite bevorzugt Visual Basic Kleinbuchstaben. Ich denke, BBC BASIC war im Auslieferungszustand in Großbuchstaben geschrieben. Ich verwende die Version unter bbcbasic.co.uk/bbcwin/bbcwin.html . Es ist Großbuchstaben in der Website und IDE, also würde ich sagen, dass die Großbuchstaben-Version korrekter ist. Aber ich denke nicht, dass es wichtig ist.
Level River St
Ahh okay, ich werde mit der Großbuchstabenversion weitermachen
Beta Decay
8

Mathematica - 177

r[x_, y_] := Sequence[x, RotationTransform[π/3, x]@y, y]
Graphics@Polygon@Nest[
 ReplaceList[#, {___, x_, y_, ___}  Sequence[x,r[2 x/3 + y/3, 2 y/3 + x/3], y]
  ] &, {{0, 0}, {.5, √3/2}, {1, 0}, {0, 0}}, Input[]]

Bildbeschreibung hier eingeben

Bonusclip zum Variieren des Winkels des Mittelstücks

Bildbeschreibung hier eingeben

Swish
quelle
6

Python 3 - 139

Verwendet die Turtle-Grafikbibliothek.

from turtle import*
b=int(input())
a=eval(("FR"*3)+".replace('F','FLFRFLF')"*~-b)
for j in a:fd(9/b*("G">j));rt(60*(2-3*("Q">j))*("K"<j))])
Beta-Zerfall
quelle
Cool. Ich mag Ihren stringbasierten Ansatz, die Form mit nicht mehr als zwei Codezeilen zu finden! Aber können Sie nicht überprüfen "G">j, "Q"<jund verwenden Sie fd(9/b)3 Bytes speichern? Außerdem können Sie vermeiden, dass sich die ifAnweisungen beispielsweise ("G">j)mit dem Argument multiplizieren, 9/bund sie alle in einer Zeile dahinter setzen for. Oh! Dann können Sie sogar kombinieren rtund ltverwenden120*(...)-60*(...)
Falko
Dies scheint die Koch-Schneeflockeneingabe + 1 zu rendern. Eine Eingabe von 1 sollte nur ein Dreieck sein, wie das obige Bild zeigt.
@Falko Danke für all diese Hilfe!
Beta Decay
@ hosch250 Bearbeitet
Beta-Zerfall
Jetzt zeichnet es nichts mehr und eine Eingabe von 1 erzeugt eine Division durch 0 Fehler.
4

Python 3, 117 Bytes

from turtle import*
ht();n=int(input())-1
for c in eval("'101'.join("*n+"'0'*4"+")"*n):rt(60+180*(c<'1'));fd(99/3**n)

Methode:

  • Die Lösung verwendet Pythons Schildkrötengrafiken.
  • n ist input - 1
  • Ausgehend von der Zeichenkette verbinden 0000wir jedes Zeichen 101 nmit dem eval-Trick (danke an @xnor dafür).
  • Für jedes Zeichen in der letzten Zeichenfolge drehen wir uns um 60 Grad nach rechts oder 120 Grad nach links, basierend auf dem Zeichenwert ( 1oder 0), und bewegen uns dann um eine Länge ( 99/3^n) vorwärts, die allen eine ähnliche Größe garantiertn .
  • Der letzte Teil 0der Zeichenfolge ist unbrauchbar, 0zeichnet jedoch nur dieselbe Linie neu, die beim ersten Mal gezeichnet wurde .

Beispielausgabe für input = 3:

Koch

randomra
quelle
2

R: 240 175

Da ich versuche, mich um R zu kümmern, ist hier eine andere Version. Es gibt wahrscheinlich viel bessere Möglichkeiten, dies zu tun, und ich freue mich über Hinweise. Was ich getan habe, scheint sehr verworren zu sein.

n=readline();d=c(0,-120,-240);c=1;while(c<n){c=c+1;e=c();for(i in 1:length(d)){e=c(e,d[i],d[i]+60,d[i]-60,d[i])};d=e};f=pi/180;plot(cumsum(sin(d*f)),cumsum(cos(d*f)),type="l")

Bildbeschreibung hier eingeben

MickyT
quelle
2

Wise fwom youw gwave ...

Ich wusste, dass ich versuchen würde, dies in Befunge-98 mit TURT zu implementieren, aber ich konnte nicht herausfinden, wie ich das machen sollte, und saß mehrere Monate darauf. Jetzt, erst kürzlich, habe ich einen Weg gefunden, dies ohne Selbstmodifikation zu tun! Und so...

Befunge-98 mit dem TURT-Fingerabdruck, 103

;v;"TRUT"4(02-&:0\:0\1P>:3+:4`!*;
>j$;space makes me cry;^
^>1-:01-\:0\:01-\:0
0>I@
^>6a*L
^>ca*R
^>fF

Lassen Sie uns zunächst einige Implementierungsdetails aus dem Weg räumen:

  • Ich habe dies mit CCBI 2.1 getestet , dessen Implementierung von TURT (dem Turtle Graphics Fingerprint) bewirkt, dass Idas Bild in eine SVG-Datei "gedruckt" wird. Wenn Sie dies in CCBI ohne das Befehlsargument --turt-line=PATHausführen, wird es standardmäßig als Datei mit dem Namen CCBI_TURT.svg ausgegeben. Dies ist der nächste Punkt, den ich erreichen könnte, um "eine grafische Darstellung der Schneeflocke auf dem Bildschirm zu drucken". mit verfügbaren Funge-Dolmetschern, die ich finden konnte. Vielleicht gibt es eines Tages einen besseren Dolmetscher, der eine grafische Darstellung für die Schildkröte bietet, aber fürs Erste ...
  • Am Ende muss eine neue Zeile stehen, damit CCBI diese ohne Hängen ausführen kann (dies ist in der Zeichenanzahl enthalten). Ich weiß es schon gut?

Grundsätzlich funktioniert dies, indem der Stack als eine Art provisorisches L-System verwendet und im laufenden Betrieb erweitert wird. Bei jedem Durchgang lautet die oberste Zahl auf dem Stapel:

  • -2, dann wird gedruckt und angehalten;
  • -1, die Schildkröte dreht sich um 60 Grad gegen den Uhrzeigersinn;
  • 0, es dreht sich im Uhrzeigersinn um 120 Grad;
  • 1, bewegt es sich vorwärts (um 15 Pixel hier, aber Sie können es ändern, indem Sie das fin der letzten Zeile ändern );
  • eine Zahl n , die 2 oder größer ist, wird dann auf dem Stapel auf erweitert n-1, -1, n-1, 0, n-1, -1, n-1.

Denn n = 10dieser Vorgang dauert sehr lange (ein paar Minuten auf meinem System), und die resultierende SVG ist ~ 10 MB groß und unsichtbar , wenn im Browser angezeigt , weil Sie nicht die Größe der Pinsel TURT anpassen können. IrfanView scheint anständig zu funktionieren, wenn Sie die richtigen Plugins haben. Ich bin mit SVG nicht besonders vertraut, daher weiß ich nicht, wie diese Dateien angezeigt werden sollen (besonders wenn sie wirklich groß sind).

Hey, zumindest funktioniert es - was, wenn man bedenkt, dass es Befunge ist, etwas ist, wofür man allein dankbar ist.

Kasran
quelle
1

Python 2, 127 Bytes

from turtle import *
def L(l,d=input()-1):
 for x in[1,-2,1,0]:[L(l,d-1),rt(60*x)] if d>0 else fd(l)
for i in'lol':lt(120);L(9)
Dieter
quelle
1
Grats für den 50.000sten Post hier.
Andrew