Penrose tiling: Difference between revisions

Added Fōrmulæ entry
(Added Fōrmulæ entry)
 
(12 intermediate revisions by 10 users not shown)
Line 31:
* [http://preshing.com/20110831/penrose-tiling-explained/ Deflation explained for Kite and Dart, includes Python code (preshing.com)]
<br><br>
 
=={{header|11l}}==
{{trans|Python}}
 
<syntaxhighlight lang="11l">
F penrose(depth)
print(‘<svg viewBox="-100 -100 200 200" xmlns="http://www.w3.org/2000/svg">
<defs>
<path id="A0" d="M 80.90169943749474 58.778525229247315 L 0 0 100 0" stroke="black" fill="#8bc" />
<path id="B0" d="M 0 0 80.90169943749474 58.778525229247315 161.80339887498948 0" stroke="black" fill="#97e" />’)
 
L(d) 0 .< depth
print(‘ <g id="A’(d + 1)‘" transform="translate(100, 0) scale(0.6180339887498949)">
<use href="#A’d‘" transform="rotate(108)" />
<use href="#B’d‘" transform="scale(-1, 1)" />
</g>
<g id="B’(d + 1)‘">
<use href="#A’(d + 1)‘" />
<use href="#B’d‘" transform="translate(100, 0) scale(0.6180339887498949) rotate(144) translate(-80.90169943749474,-58.778525229247315)"/>
</g>’)
 
print(‘ <g id="G">
<use href="#A’depth‘"/>
<use href="#A’depth‘" transform="scale(1, -1)" />
</g>
</defs>
<g transform="scale(2, 2)">
<use href="#G" transform="rotate(-144)" />
<use href="#G" transform="rotate(-72)" />
<use href="#G" transform="rotate(0)" />
<use href="#G" transform="rotate(72)" />
<use href="#G" transform="rotate(144)" />
</g>
</svg>’)
 
penrose(6)
</syntaxhighlight>
 
=={{header|C++}}==
{{trans|Nim}}
<langsyntaxhighlight lang="cpp">#include <cmath>
#include <cstdlib>
#include <fstream>
Line 117 ⟶ 154:
out << "</g>\n</svg>\n";
return EXIT_SUCCESS;
}</langsyntaxhighlight>
 
{{out}}
[[Media:Penrose tiling cpp.svg]]
Writes a file in SVG format similar to that produced by the Perl solution.
 
=={{header|EasyLang}}==
[https://easylang.online/show/#cod=jVTLbqQwELz7K0oWymFbRpnMbm4c/RXIBwOexIoDCJMM8/er5jXOzKy0EkKmqlztbgr6oasR4iW6qUdw3y4gh51895lh+AouZqVBLgCcugEBY7eoGAFg2wwFpFwfWVNn8C3iONTvdoir18qvEo8CB8TR9XhZHNu92FUJwJ823BsUqLMfLMDFil0CwsHcKqrB2Q8cfsC5eLTkXp6SIhsVz7bfRmLbmc1FLuJo64+Sj1XCiH6bYzPY86aecIFt3xDaN+SLX/CtO/tmfMdzfmTgs/t2LBT/MT5/WhqWWl6PPYEK1F1E4wf84lpX7sJc9O0jjk+yFQbgwu6uEnfeqAru4l5HNzr6h65MdNvUngpMD9HLQ7Txw72vSXwDijlG6550PMUKBii8mHQ4KZMmh5vZuQRPCkAdr3j6DrfgcETWGPAIKkN0f5Ni/8Y4RtJKyFoTNVoppSpdqnpeWW2IJGQlIYmhRpczzCLDTC0hldVElS6JaDExSkI2zCgGiKwuqZlXlTa8V3KWICWM2H4Cr7efv7iN9Z9nvo6v+C3EXw== Run it]
 
<syntaxhighlight>
proc lsysexp level . axiom$ rules$[] .
for l to level
an$ = ""
for c$ in strchars axiom$
for i = 1 step 2 to len rules$[]
if rules$[i] = c$
c$ = rules$[i + 1]
break 1
.
.
an$ &= c$
.
swap axiom$ an$
.
.
stack[] = [ ]
proc lsysdraw axiom$ x y ang lng . .
linewidth 0.3
move x y
for c$ in strchars axiom$
if c$ = "E"
x += cos dir * lng
y += sin dir * lng
line x y
elif c$ = "-"
dir -= ang
elif c$ = "+"
dir += ang
elif c$ = "["
stack[] &= x
stack[] &= y
stack[] &= dir
elif c$ = "]"
l = len stack[]
x = stack[l - 2]
y = stack[l - 1]
dir = stack[l]
len stack[] -3
move x y
.
.
.
axiom$ = "[b]++[b]++[b]++[b]++[b]"
rules$[] = [ "a" "cE++dE----bE[-cE----aE]++" "b" "+cE--dE[---aE--bE]+" "c" "-aE++bE[+++cE++dE]-" "d" "--cE++++aE[+dE++++bE]--bE" "E" "" ]
lsysexp 6 axiom$ rules$[]
lsysdraw axiom$ 50 50 36 4
</syntaxhighlight>
 
=={{header|FreeBASIC}}==
{{trans|Phython}}
Not much of a FreeBASIC program: majority of this code is string literals that dumps an SVG on output.
<syntaxhighlight lang="vb">Sub penrose(depth As Integer)
Dim As String svg
svg = "<svg viewBox=""-100 -100 200 200"" xmlns=""http://www.w3.org/2000/svg"">" + !"\n"
svg &= " <defs>" + !"\n"
svg &= " <path id=""A0"" d=""M 80.90169943749474 58.778525229247315 L 0 0 100 0"" stroke=""black"" fill=""#8bc"" />" + !"\n"
svg &= " <path id=""B0"" d=""M 0 0 80.90169943749474 58.778525229247315 161.80339887498948 0"" stroke=""black"" fill=""#97e"" />" + !"\n"
For d As Integer = 0 To 5
svg &= " <g id=""A" : svg &= (d+1) : svg &= """ transform=""translate(100, 0) scale(0.6180339887498949)"">" + !"\n"
svg += " <use href=" & """" & "#A" & d & """ transform=""rotate(108)"" />" + !"\n"
svg &= " <use href=" & """" & "#B" & d & """ transform=""scale(-1, 1)"" />" + !"\n"
svg &= " </g>" + !"\n"
svg &= " <g id=""B" & d+1 & """>" + !"\n"
svg &= " <use href=" & """" & "#A" & d+1 & """ />" + !"\n"
svg &= " <use href=" & """" & "#B" & d & """ transform=""translate(100, 0) scale(0.6180339887498949) rotate(144) translate(-80.90169943749474,-58.778525229247315)""/>" + !"\n"
svg &= " </g>" + !"\n"
Next
svg &= " <g id=""G"">" + !"\n"
svg &= " <use href=""#A6""/>" + !"\n"
svg &= " <use href=""#A6"" transform=""scale(1, -1)"" />" + !"\n"
svg &= " </g>" + !"\n"
svg &= " </defs>" + !"\n"
svg &= " <g transform=""scale(2, 2)"">" + !"\n"
svg &= " <use href=""#G"" transform=""rotate(-144)"" />" + !"\n"
svg &= " <use href=""#G"" transform=""rotate(-72)"" />" + !"\n"
svg &= " <use href=""#G"" transform=""rotate(0)"" />" + !"\n"
svg &= " <use href=""#G"" transform=""rotate(72)"" />" + !"\n"
svg &= " <use href=""#G"" transform=""rotate(144)"" />" + !"\n"
svg &= " </g>" + !"\n"
svg &= "</svg>"
Print #1, svg
End Sub
 
Open "Penrose_tiling.svg" For Output As #1
penrose(6)
Close #1</syntaxhighlight>
 
=={{header|Fōrmulæ}}==
 
{{FormulaeEntry|page=https://formulae.org/?script=examples/L-system}}
 
'''Solution'''
 
It can be done using an [[wp:L-system|L-system]]. There are generic functions written in Fōrmulæ to compute an L-system in the page [[L-system#Fōrmulæ | L-system]].
 
The program that creates a Penrose tiling is:
 
[[File:Fōrmulæ - L-system - Penrose tiling 01.png]]
 
[[File:Fōrmulæ - L-system - Penrose tiling 02.png]]
 
=={{header|Go}}==
{{libheader|Go Graphics}}
{{trans|Java}}
<langsyntaxhighlight lang="go">package main
 
import (
Line 234 ⟶ 379:
drawTiles(dc, tiles)
dc.SavePNG("penrose_tiling.png")
}</langsyntaxhighlight>
 
{{out}}
Line 240 ⟶ 385:
Image same as Java entry.
</pre>
 
=={{header|J}}==
{{trans|perl}}
<syntaxhighlight lang="j">require'format/printf'
penrosesvg=: {{
penrose=. rplc&(".{{)n
'A';'';
'M';'OA++PA----NA(-OA----MA)++';
'N';'+OA--PA(---MA--NA)+';
'O';'-MA++NA(+++OA++PA)-';
'P';'--OA++++MA(+PA++++NA)--NA'
}}-.LF)^:y '(N)++(N)++(N)++(N)++(N)'
LINE=. 2 2$0
A=. a=. o.%5
R=. 20
LINES=. STACK=. EMPTY
for_ch. penrose do.
select. ch
case. 'A' do. LINES=. LINES,,LINE=. (R*0,:2 1 o. A)+"1 {:LINE
case. '+' do. A=. A+a
case. '-' do. A=. A-a
case. '(' do. STACK=. STACK, A;LINE
case. ')' do. STACK=. }: STACK [ 'A LINE'=. {: STACK
end.
end.
OFF=. 25+>.>./,LINES=. ~.LINES
assert 1<(F=.'penrose_tiling_%d.svg' sprintf y) fwrite~ {{)n
<svg xmlns="http://www.w3.org/2000/svg" height="%d" width="%d">
<rect height="100%%" width="100%%" style="fill:black" />
%s
</svg>
}} sprintf (2#<2*OFF),<}:,{{)n
<line x1="%.1f" y1="%.1f" x2="%.1f" y2="%.1f" style="stroke:rgb(255,165,0)"/>
}} sprintf"1 OFF+LINES
(jpathsep 1!:43''),'/',F
}}</syntaxhighlight>
 
Example images (linked): [[j:File:Penrose_tiling_1.svg|<code>penrosesvg 1</code>]], [[j:File:Penrose_tiling_2.svg|<code>penrosesvg 2</code>]], [[j:File:Penrose_tiling_3.svg|<code>penrosesvg 3</code>]], [[j:File:Penrose_tiling_4.svg|<code>penrosesvg 4</code>]], [[j:File:Penrose_tiling_5.svg|<code>penrosesvg 5</code>]]
 
=={{header|Java}}==
[[File:Penrose_java.png|300px|thumb|right]]
{{works with|Java|8}}
<langsyntaxhighlight lang="java">import java.awt.*;
import java.util.List;
import java.awt.geom.Path2D;
Line 382 ⟶ 565:
});
}
}</langsyntaxhighlight>
 
=={{header|jq}}==
'''Adapted from [[#Perl|Perl]]'''
{{works with|jq}}
'''Works with gojq, the Go implementation of jq'''
 
The SVG viewBox parameters are computed dynamically.
<langsyntaxhighlight lang="jq">def pi: 4 * (1|atan);
 
def rules:
Line 462 ⟶ 645:
 
penrose_tiling(5)
| svg</langsyntaxhighlight>
{{out}}
See https://imgur.com/gallery/UflFbPw
 
=={{header|Julia}}==
{{trans|Perl}}
<langsyntaxhighlight lang="julia">using Printf
 
function drawpenrose()
Line 505 ⟶ 690:
 
drawpenrose()
</syntaxhighlight>
</lang>
 
=={{header|Kotlin}}==
{{trans|Java}}
<langsyntaxhighlight lang="scala">// version 1.1.2
 
import java.awt.*
Line 642 ⟶ 827:
}
}
}</langsyntaxhighlight>
 
=={{header|Nim}}==
{{trans|Phix}}
This is a translation of the Lindenmayer Phix version translated itself from Perl.
<langsyntaxhighlight Nimlang="nim">import math, strformat, tables
 
const Lindenmayer = {'A': "",
Line 695 ⟶ 880:
"""
svgFile.write svg, "</svg>"
svgFile.close()</langsyntaxhighlight>
 
{{out}}
Line 701 ⟶ 886:
 
=={{header|Perl}}==
<langsyntaxhighlight lang="perl">use constant pi => 2 * atan2(1, 0);
 
# Generated with a P3 tile set using a Lindenmayer system.
Line 734 ⟶ 919:
open $fh, '>', 'penrose_tiling.svg';
print $fh qq{<svg xmlns="http://www.w3.org/2000/svg" height="350" width="350"> <rect height="100%" width="100%" style="fill:black" />\n$svg</svg>};
close $fh;</langsyntaxhighlight>
[https://github.com/SqrtNegInf/Rosettacode-Perl5-Smoke/blob/master/ref/penrose_tiling.svg Penrose tiling] (offsite image)
 
Line 742 ⟶ 927:
{{libheader|Phix/online}}
You can run this online [http://phix.x10.mx/p2js/Penrose_tiling.htm here].
<!--<langsyntaxhighlight Phixlang="phix">(phixonline)-->
<span style="color: #000080;font-style:italic;">--
-- demo\rosetta\Penrose_tiling.exw
Line 877 ⟶ 1,062:
<span style="color: #000000;">main</span><span style="color: #0000FF;">()</span>
<!--</langsyntaxhighlight>-->
 
=== Lindenmayer/svg ===
{{trans|Perl}} Same output, obviously the resulting file can be opened in a separate browser.
<!--<langsyntaxhighlight Phixlang="phix">(phixonline)-->
<span style="color: #008080;">without</span> <span style="color: #008080;">js</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">Lindenmayer</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">new_dict</span><span style="color: #0000FF;">({{</span><span style="color: #008000;">'A'</span><span style="color: #0000FF;">,</span><span style="color: #008000;">""</span><span style="color: #0000FF;">},</span>
Line 925 ⟶ 1,110:
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fn</span><span style="color: #0000FF;">,</span><span style="color: #000000;">svgfmt</span><span style="color: #0000FF;">,</span><span style="color: #000000;">svg</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">close</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fn</span><span style="color: #0000FF;">)</span>
<!--</langsyntaxhighlight>-->
 
=={{header|Processing}}==
===LSystem===
<syntaxhighlight lang="java">
class LSystem
{
int steps = 0;
 
String axiom;
String rule;
String production;
 
float startLength;
float drawLength;
float theta;
 
int generations;
 
LSystem() {
axiom = "F";
rule = "F+F-F";
startLength = 190.0;
theta = radians(120.0);
reset();
}
 
void reset() {
production = axiom;
drawLength = startLength;
generations = 0;
}
 
int getAge() {
return generations;
}
 
void render() {
translate(width/2, height/2);
steps += 5;
if (steps > production.length()) {
steps = production.length();
}
for (int i = 0; i < steps; i++) {
char step = production.charAt(i);
if (step == 'F') {
rect(0, 0, -drawLength, -drawLength);
noFill();
translate(0, -drawLength);
}
else if (step == '+') {
rotate(theta);
}
else if (step == '-') {
rotate(-theta);
}
else if (step == '[') {
pushMatrix();
}
else if (step == ']') {
popMatrix();
}
}
}
 
void simulate(int gen) {
while (getAge() < gen) {
production = iterate(production, rule);
}
}
 
String iterate(String prod_, String rule_) {
drawLength = drawLength * 0.6;
generations++;
String newProduction = prod_;
newProduction = newProduction.replaceAll("F", rule_);
return newProduction;
}
}
</syntaxhighlight>
===PenroseLSystem===
<syntaxhighlight lang="java">
class PenroseLSystem extends LSystem {
 
int steps = 0;
float somestep = 0.1;
String ruleW;
String ruleX;
String ruleY;
String ruleZ;
 
PenroseLSystem() {
axiom = "[X]++[X]++[X]++[X]++[X]";
ruleW = "YF++ZF4-XF[-YF4-WF]++";
ruleX = "+YF--ZF[3-WF--XF]+";
ruleY = "-WF++XF[+++YF++ZF]-";
ruleZ = "--YF++++WF[+ZF++++XF]--XF";
startLength = 460.0;
theta = radians(36);
reset();
}
 
void useRule(String r_) {
rule = r_;
}
 
void useAxiom(String a_) {
axiom = a_;
}
 
void useLength(float l_) {
startLength = l_;
}
 
void useTheta(float t_) {
theta = radians(t_);
}
 
void reset() {
production = axiom;
drawLength = startLength;
generations = 0;
}
 
int getAge() {
return generations;
}
 
void render() {
translate(width/2, height/2);
int pushes = 0;
int repeats = 1;
steps += 12;
if (steps > production.length()) {
steps = production.length();
}
 
for (int i = 0; i < steps; i++) {
char step = production.charAt(i);
if (step == 'F') {
stroke(255, 60);
for (int j = 0; j < repeats; j++) {
line(0, 0, 0, -drawLength);
noFill();
translate(0, -drawLength);
}
repeats = 1;
}
else if (step == '+') {
for (int j = 0; j < repeats; j++) {
rotate(theta);
}
repeats = 1;
}
else if (step == '-') {
for (int j =0; j < repeats; j++) {
rotate(-theta);
}
repeats = 1;
}
else if (step == '[') {
pushes++;
pushMatrix();
}
else if (step == ']') {
popMatrix();
pushes--;
}
else if ( (step >= 48) && (step <= 57) ) {
repeats = (int)step - 48;
}
}
 
// Unpush if we need too
while (pushes > 0) {
popMatrix();
pushes--;
}
}
 
String iterate(String prod_, String rule_) {
String newProduction = "";
for (int i = 0; i < prod_.length(); i++) {
char step = production.charAt(i);
if (step == 'W') {
newProduction = newProduction + ruleW;
}
else if (step == 'X') {
newProduction = newProduction + ruleX;
}
else if (step == 'Y') {
newProduction = newProduction + ruleY;
}
else if (step == 'Z') {
newProduction = newProduction + ruleZ;
}
else {
if (step != 'F') {
newProduction = newProduction + step;
}
}
}
 
drawLength = drawLength * 0.5;
generations++;
return newProduction;
}
 
}
</syntaxhighlight>
===PenroseTile===
<syntaxhighlight lang="java">
PenroseLSystem ds;
 
void setup() {
size(1000, 1000);
ds = new PenroseLSystem();
ds.simulate(5);
}
 
void draw() {
background(0);
ds.render();
}
</syntaxhighlight>
 
=={{header|Python}}==
Not much of a python program: majority of this code is string literals that dumps an SVG on output.
<syntaxhighlight lang="python">def penrose(depth):
print('''<svg viewBox="-100 -100 200 200" xmlns="http://www.w3.org/2000/svg">
<defs>
<path id="A0" d="M 80.90169943749474 58.778525229247315 L 0 0 100 0" stroke="black" fill="#8bc" />
<path id="B0" d="M 0 0 80.90169943749474 58.778525229247315 161.80339887498948 0" stroke="black" fill="#97e" />''')
 
for d in range(depth):
print(f''' <g id="A{d+1}" transform="translate(100, 0) scale(0.6180339887498949)">
<use href="#A{d}" transform="rotate(108)" />
<use href="#B{d}" transform="scale(-1, 1)" />
</g>
<g id="B{d+1}">
<use href="#A{d+1}" />
<use href="#B{d}" transform="translate(100, 0) scale(0.6180339887498949) rotate(144) translate(-80.90169943749474,-58.778525229247315)"/>
</g>''')
 
print(f''' <g id="G">
<use href="#A{d+1}"/>
<use href="#A{d+1}" transform="scale(1, -1)" />
</g>
</defs>
<g transform="scale(2, 2)">
<use href="#G" transform="rotate(-144)" />
<use href="#G" transform="rotate(-72)" />
<use href="#G" transform="rotate(0)" />
<use href="#G" transform="rotate(72)" />
<use href="#G" transform="rotate(144)" />
</g>
</svg>''')
 
penrose(6)</syntaxhighlight>
 
=={{header|Racket}}==
Line 931 ⟶ 1,374:
{{trans|Perl}}
 
<langsyntaxhighlight lang="racket">#lang racket
(require racket/draw)
Line 968 ⟶ 1,411:
target)
(make-curve 500 4 20 80 (make-color 255 255 0) (make-color 0 0 0))</langsyntaxhighlight>
 
=={{header|Raku}}==
Line 975 ⟶ 1,418:
Generated with a P3 tile set using a Lindenmayer system.
 
<syntaxhighlight lang="raku" perl6line>use SVG;
 
role Lindenmayer {
Line 1,016 ⟶ 1,459:
|@lines,
],
);</langsyntaxhighlight>
See: [https://github.com/thundergnat/rc/blob/master/img/penrose-perl6.svg Penrose tiling image]
 
Line 1,023 ⟶ 1,466:
{{libheader|Scala Java Swing interoperability}}
{{works with|Scala|2.13}}
<langsyntaxhighlight Scalalang="scala">import java.awt.{BorderLayout, Color, Dimension, Graphics, Graphics2D, RenderingHints}
import java.awt.geom.Path2D
 
Line 1,113 ⟶ 1,556:
}
 
}</langsyntaxhighlight>
 
=={{header|Sidef}}==
Using the LSystem class defined at [https://rosettacode.org/wiki/Hilbert_curve#Sidef Hilbert curve].
<langsyntaxhighlight lang="ruby">var rules = Hash(
a => 'cE++dE----bE[-cE----aE]++',
b => '+cE--dE[---aE--bE]+',
Line 1,138 ⟶ 1,581:
)
 
lsys.execute('[b]++[b]++[b]++[b]++[b]', 5, "penrose_tiling.png", rules)</langsyntaxhighlight>
 
Output image: [https://github.com/trizen/rc/blob/master/img/penrose-tiling-sidef.png Penrose tiling]
Line 1,148 ⟶ 1,591:
{{libheader|Wren-set}}
{{libheader|Wren-polygon}}
<langsyntaxhighlight ecmascriptlang="wren">import "graphics" for Canvas, Color
import "dome" for Window
import "math" for Math
Line 1,263 ⟶ 1,706:
}
 
var Game = PenroseTiling.new(700, 450)</langsyntaxhighlight>
2,120

edits