Pentagram: Difference between revisions
(→{{header|Java}}: more compact) |
(→{{header|Tcl}}: added zkl) |
||
Line 515:
</lang>
=={{header|zkl}}==
{{trans|Perl 6}}
Generate an SVG file to STDOUT. Redirect to a file to capture and display it.
<lang zkl>const DIM=200, SIDES=5, A=360/SIDES, R=DIM.toFloat();
vs:=[0.0..360-A,A].walk(); // angles of vertices
#<<<
0'|<?xml version="1.0" standalone="no" ?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
"http://www.w3.org/TR/2001/PR-SVG-20010719/DTD/svg10.dtd">
<svg height="%d" width="%d" style="" xmlns="http://www.w3.org/2000/svg">
<rect height="100%" width="100%" style="fill:bisque;" />|
#<<<
.fmt(DIM*2, DIM*2).println();
var vertices=vs.pump(List,fcn(a){ R.toRectangular(a.toRad()) }); //( (x,y), (x,y)...
SIDES.pump(String,pline).println(); // the line pairs that draw the pentagram
fcn pline(n){ a:=(n + 2)%SIDES; // (n,a) are the endpoints of the right leg
pts:=String("\"", ("% 0.3f,% 0.3f "*2), "\" "); // two points
vs:='wrap(){ T(n,a).pump(List,vertices.get).flatten() }; //(x,y, x,y)
String(
(0'|<polyline points=| + pts).fmt(vs().xplode()),
0'|style="fill:seashell; stroke:blue; stroke-width:3;" |,
0'|transform="translate(%d,%d) rotate(-18)"|.fmt(DIM,DIM),
" />\n"
);
}
println("</svg>");</lang>
{{out}}
<pre>
$ zkl bbb > pentagram.svg
$ cat pentagram.svg
<?xml version="1.0" standalone="no" ?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
"http://www.w3.org/TR/2001/PR-SVG-20010719/DTD/svg10.dtd">
<svg height="400" width="400" style="" xmlns="http://www.w3.org/2000/svg">
<rect height="100%" width="100%" style="fill:bisque;" />
<polyline points=" 200.000, 0.000 -161.803, 117.557 " style="fill:seashell; stroke:blue; stroke-width:3;" transform="translate(200,200) rotate(-18)" />
<polyline points=" 61.803, 190.211 -161.803,-117.557 " style="fill:seashell; stroke:blue; stroke-width:3;" transform="translate(200,200) rotate(-18)" />
<polyline points="-161.803, 117.557 61.803,-190.211 " style="fill:seashell; stroke:blue; stroke-width:3;" transform="translate(200,200) rotate(-18)" />
<polyline points="-161.803,-117.557 200.000, 0.000 " style="fill:seashell; stroke:blue; stroke-width:3;" transform="translate(200,200) rotate(-18)" />
<polyline points=" 61.803,-190.211 61.803, 190.211 " style="fill:seashell; stroke:blue; stroke-width:3;" transform="translate(200,200) rotate(-18)" />
</svg>
</pre>
|
Revision as of 19:20, 2 August 2016
You are encouraged to solve this task according to the task description, using any language you may know.
A pentagram is a star polygon, consisting of a central pentagon of which each side forms the base of an isosceles triangle. The vertex of each triangle, a point of the star, is 36 degrees.
- Task
Draw (or print) a regular pentagram, in any orientation. Use a different color (or token) for stroke and fill, and background. For the fill it should be assumed that all points inside the triangles and the pentagon are inside the pentagram.
- See also
Haskell
This uses the Diagrams library to create an SVG drawing. Compiling, then running it like:
pentagram -w 400 -o pentagram_hs.svg
creates a 400x400 SVG file. <lang haskell>-- Extract the vertices of a pentagon, re-ordering them so that drawing lines -- from one to the next forms a pentagram. Set the line's thickness and its -- colour, as well as the fill and background colours. Make the background a -- bit larger than the pentagram.
import Diagrams.Prelude import Diagrams.Backend.SVG.CmdLine
pentagram = let [a, b, c, d, e] = trailVertices $ pentagon 1
in [a, c, e, b, d] # fromVertices # closeTrail # strokeTrail # lw ultraThick # fc springgreen # lc blue # bgFrame 0.2 bisque
main = mainWith (pentagram :: Diagram B)</lang>
J
Probably the simplest approach is:
<lang j>require'plot' plot j./2 1 o./180p_1 %~ 72*i. 6</lang>
This will give a pentagram with a blue border and a white interior.
Java
<lang java>import java.awt.*; import java.awt.geom.Path2D; import javax.swing.*;
public class Pentagram extends JPanel {
final double degrees144 = Math.toRadians(144);
public Pentagram() { setPreferredSize(new Dimension(640, 640)); setBackground(Color.white); }
private void drawPentagram(Graphics2D g, int len, int x, int y, Color fill, Color stroke) { double angle = 0;
Path2D p = new Path2D.Float(); p.moveTo(x, y);
for (int i = 0; i < 5; i++) { int x2 = x + (int) (Math.cos(angle) * len); int y2 = y + (int) (Math.sin(-angle) * len); p.lineTo(x2, y2); x = x2; y = y2; angle -= degrees144; } p.closePath();
g.setColor(fill); g.fill(p);
g.setColor(stroke); g.draw(p); }
@Override public void paintComponent(Graphics gg) { super.paintComponent(gg); Graphics2D g = (Graphics2D) gg;
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setStroke(new BasicStroke(5, BasicStroke.CAP_ROUND, 0));
drawPentagram(g, 500, 70, 250, new Color(0x6495ED), Color.darkGray); }
public static void main(String[] args) { SwingUtilities.invokeLater(() -> { JFrame f = new JFrame(); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.setTitle("Pentagram"); f.setResizable(false); f.add(new Pentagram(), BorderLayout.CENTER); f.pack(); f.setLocationRelativeTo(null); f.setVisible(true); }); }
}</lang>
ooRexx
<lang oorexx>/* REXX ***************************************************************
- Create a BMP file showing a pentagram
- /
pentagram='pentagram.bmp' 'erase' pentagram s='424d4600000000000000360000002800000038000000280000000100180000000000'X s=s'1000000000000000000000000000000000000000'x Say 'sl='length(s) z.0=0 white='ffffff'x red ='00ff00'x green='ff0000'x blue ='0000ff'x rd6=copies(rd,6) m=133 m=80 n=80 hor=m*8 /* 56 */ ver=n*8 /* 40 */ Say 'hor='hor Say 'ver='ver Say 'sl='length(s) s=overlay(lend(hor),s,19,4) s=overlay(lend(ver),s,23,4) Say 'sl='length(s) z.=copies('ffffff'x,3192%3) z.=copies('ffffff'x,8*m) z.0=648 s72 =RxCalcsin(72,,'D') c72 =RxCalccos(72,,'D') s144=RxCalcsin(144,,'D') c144=RxCalccos(144,,'D') xm=300 ym=300 r=200 p.0x.1=xm p.0y.1=ym+r p.0x.2=format(xm+r*s72,3,0) p.0y.2=format(ym+r*c72,3,0) p.0x.3=format(xm+r*s144,3,0) p.0y.3=format(ym+r*c144,3,0) p.0x.4=format(xm-r*s144,3,0) p.0y.4=p.0y.3 p.0x.5=format(xm-r*s72,3,0) p.0y.5=p.0y.2 Do i=1 To 5
Say p.0x.i p.0y.i End
Call line p.0x.1,p.0y.1,p.0x.3,p.0y.3 Call line p.0x.1,p.0y.1,p.0x.4,p.0y.4 Call line p.0x.2,p.0y.2,p.0x.4,p.0y.4 Call line p.0x.2,p.0y.2,p.0x.5,p.0y.5 Call line p.0x.3,p.0y.3,p.0x.5,p.0y.5
Do i=1 To z.0
s=s||z.i End
Call lineout pentagram,s Call lineout pentagram Exit
lend: Return reverse(d2c(arg(1),4))
line: Procedure Expose z. red green blue Parse Arg x0, y0, x1, y1 Say 'line' x0 y0 x1 y1 dx = abs(x1-x0) dy = abs(y1-y0) if x0 < x1 then sx = 1
else sx = -1
if y0 < y1 then sy = 1
else sy = -1
err = dx-dy
Do Forever
xxx=x0*3+2 Do yy=y0-1 To y0+1 z.yy=overlay(copies(blue,5),z.yy,xxx) End if x0 = x1 & y0 = y1 Then Leave e2 = 2*err if e2 > -dy then do err = err - dy x0 = x0 + sx end if e2 < dx then do err = err + dx y0 = y0 + sy end end
Return
- requires RxMath Library</lang>
Perl 6
Generate an SVG file to STDOUT. Redirect to a file to capture and display it. <lang perl6>constant $dim = 200; constant $sides = 5;
INIT say qq:to/STOP/;
<?xml version="1.0" standalone="no" ?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/PR-SVG-20010719/DTD/svg10.dtd"> <svg height="{$dim*2}" width="{$dim*2}" style="" xmlns="http://www.w3.org/2000/svg"> <rect height="100%" width="100%" style="fill:bisque;" /> STOP
END say '</svg>';
my @vertices = map { 0.9 * $dim * cis($_ * τ / $sides) }, ^$sides;
say pline map |*.reals, flat @vertices[0, 2 ... *], @vertices[1, 3 ... *];
sub pline (@q) {
qq:to/STOP/; <polyline points="{@q[^@q, 0, 1].fmt("%0.3f")}" style="fill:seashell; stroke:blue; stroke-width:3;" transform="translate($dim, $dim) rotate(-18)" /> STOP
}</lang> See Pentagram
PostScript
<lang postscript>%!PS-Adobe-3.0 EPSF %%BoundingBox: 0 0 200 600
/n 5 def % 5-star; can be set to other odd numbers
/s { gsave } def /r { grestore } def /g { .7 setgray } def /t { 100 exch translate } def /p { 180 90 n div sub rotate 0 0 moveto n { 0 160 rlineto 180 180 n div sub rotate } repeat closepath } def
s 570 t p s g eofill r stroke r % even-odd fill s 370 t p s g fill r stroke r % non-zero fill s 170 t p s 2 setlinewidth stroke r g fill r % non-zero, but hide inner strokes
%%EOF</lang>
The following isn't exactly what the task asks for, but it's kind of fun if you have a PS interpreter that progressively updates. The program draws a lot of stars, so it's extremely likely that some of them are pentagrams... <lang postscript>%!PS-Adobe-3.0 EPSF %%BoundingBox: 0 0 400 400
% randomly choose from 5- to 35-stars /maxpoint 35 def /minpoint 5 def /maxradius 30 def
/rnd1 { rand 16#80000000 div } def /rnd { rnd1 mul} def /rndi { 2 index sub rnd1 mul 1 index div cvi mul add} def /line { rotate 0 rlineto } def
/star { gsave /n minpoint 2 maxpoint rndi def /r maxradius rnd def /a 180 180 n div sub def /b 360 a n mul sub n div def
400 rnd 400 rnd translate 360 rnd rotate 0 0 moveto n { r a line r b line } repeat closepath rnd1 rnd1 rnd1 3 { 2 index 1 exch sub } repeat gsave setrgbcolor fill grestore setrgbcolor stroke grestore } def
0 setlinewidth 2000 {star} repeat showpage %%EOF</lang>
Python
<lang python>import turtle
turtle.bgcolor("green") t = turtle.Turtle() t.color("red", "blue") t.begin_fill() for i in range(0, 5):
t.forward(200) t.right(144)
t.end_fill()</lang>
Racket
<lang racket>#lang racket (require 2htdp/image)
(overlay
(star-polygon 100 5 2 "outline" (make-pen "blue" 4 "solid" "round" "round")) (star-polygon 100 5 2 "solid" "cyan"))</lang>
REXX
<lang rexx>/* REXX ***************************************************************
- Create a BMP file showing a pentagram
- /
Parse Version v If pos('Regina',v)>0 Then
pentagram='pentagrama.bmp'
Else
pentagram='pentagramx.bmp'
'erase' pentagram s='424d4600000000000000360000002800000038000000280000000100180000000000'X||,
'1000000000000000000000000000000000000000'x
Say 'sl='length(s) z.0=0 white='ffffff'x red ='00ff00'x green='ff0000'x blue ='0000ff'x rd6=copies(rd,6) m=133 m=80 n=80 hor=m*8 /* 56 */ ver=n*8 /* 40 */ Say 'hor='hor Say 'ver='ver Say 'sl='length(s) s=overlay(lend(hor),s,19,4) s=overlay(lend(ver),s,23,4) Say 'sl='length(s) z.=copies('ffffff'x,3192%3) z.=copies('ffffff'x,8*m) z.0=648 pi_5=2*3.14159/5 s72 =sin(pi_5 ) c72 =cos(pi_5 ) s144=sin(pi_5*2) c144=cos(pi_5*2) xm=300 ym=300 r=200 p.0x.1=xm p.0y.1=ym+r
p.0x.2=format(xm+r*s72,3,0) p.0y.2=format(ym+r*c72,3,0) p.0x.3=format(xm+r*s144,3,0) p.0y.3=format(ym+r*c144,3,0) p.0x.4=format(xm-r*s144,3,0) p.0y.4=p.0y.3 p.0x.5=format(xm-r*s72,3,0) p.0y.5=p.0y.2 Do i=1 To 5
Say p.0x.i p.0y.i End
Call line p.0x.1,p.0y.1,p.0x.3,p.0y.3 Call line p.0x.1,p.0y.1,p.0x.4,p.0y.4 Call line p.0x.2,p.0y.2,p.0x.4,p.0y.4 Call line p.0x.2,p.0y.2,p.0x.5,p.0y.5 Call line p.0x.3,p.0y.3,p.0x.5,p.0y.5
Do i=1 To z.0
s=s||z.i End
Call lineout pentagram,s Call lineout pentagram Exit
lend: Return reverse(d2c(arg(1),4))
line: Procedure Expose z. red green blue Parse Arg x0, y0, x1, y1 Say 'line' x0 y0 x1 y1 dx = abs(x1-x0) dy = abs(y1-y0) if x0 < x1 then sx = 1
else sx = -1
if y0 < y1 then sy = 1
else sy = -1
err = dx-dy
Do Forever
xxx=x0*3+2 Do yy=y0-1 To y0+1 z.yy=overlay(copies(blue,5),z.yy,xxx) End if x0 = x1 & y0 = y1 Then Leave e2 = 2*err if e2 > -dy then do err = err - dy x0 = x0 + sx end if e2 < dx then do err = err + dx y0 = y0 + sy end end
Return
sin: Procedure /* REXX ****************************************************************
- Return sin(x<,p>) -- with the specified precision
- /
Parse Arg x,prec If prec= Then prec=9 Numeric Digits (2*prec) Numeric Fuzz 3 pi=3.14159 Do While x>pi x=x-pi End Do While x<-pi x=x+pi End o=x u=1 r=x Do i=3 By 2 ra=r o=-o*x*x u=u*i*(i-1) r=r+(o/u) If r=ra Then Leave End Numeric Digits prec Return r+0
cos: Procedure /* REXX ****************************************************************
- Return cos(x) -- with specified precision
- /
Parse Arg x,prec If prec= Then prec=9 Numeric Digits (2*prec) Numeric Fuzz 3 o=1 u=1 r=1 Do i=1 By 2 ra=r o=-o*x*x u=u*i*(i+1) r=r+(o/u) If r=ra Then Leave End Numeric Digits prec Return r+0
sqrt: Procedure /* REXX ***************************************************************
- EXEC to calculate the square root of a = 2 with high precision
- /
Parse Arg x,prec If prec<9 Then prec=9 prec1=2*prec eps=10**(-prec1) k = 1 Numeric Digits 3 r0= x r = 1 Do i=1 By 1 Until r=r0 | (abs(r*r-x)<eps) r0 = r r = (r + x/r) / 2 k = min(prec1,2*k) Numeric Digits (k + 5) End Numeric Digits prec Return r+0</lang>
Tcl
This implementation draws a simple pentagram on a Canvas widget.
<lang Tcl> package require Tk 8.6 ;# lmap is new in Tcl/Tk 8.6
set pi [expr 4*atan(1)]
pack [canvas .c] -expand yes -fill both ;# create the canvas
update ;# draw everything so the dimensions are accurate
set w [winfo width .c] ;# calculate appropriate dimensions set h [winfo height .c] set r [expr {min($w,$h) * 0.45}]
set points [lmap n {0 1 2 3 4 5} {
set n [expr {$n * 2}] set y [expr {sin($pi * 2 * $n / 5) * $r + $h / 2}] set x [expr {cos($pi * 2 * $n / 5) * $r + $w / 2}] list $x $y
}] set points [concat {*}$points] ;# flatten the list
puts [.c create line $points]
- a fun reader exercise is to make the shape respond to mouse events,
- or animate it!
</lang>
zkl
Generate an SVG file to STDOUT. Redirect to a file to capture and display it. <lang zkl>const DIM=200, SIDES=5, A=360/SIDES, R=DIM.toFloat(); vs:=[0.0..360-A,A].walk(); // angles of vertices
- <<<
0'|<?xml version="1.0" standalone="no" ?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/PR-SVG-20010719/DTD/svg10.dtd"> <svg height="%d" width="%d" style="" xmlns="http://www.w3.org/2000/svg"> <rect height="100%" width="100%" style="fill:bisque;" />|
- <<<
.fmt(DIM*2, DIM*2).println();
var vertices=vs.pump(List,fcn(a){ R.toRectangular(a.toRad()) }); //( (x,y), (x,y)... SIDES.pump(String,pline).println(); // the line pairs that draw the pentagram
fcn pline(n){ a:=(n + 2)%SIDES; // (n,a) are the endpoints of the right leg
pts:=String("\"", ("% 0.3f,% 0.3f "*2), "\" "); // two points vs:='wrap(){ T(n,a).pump(List,vertices.get).flatten() }; //(x,y, x,y) String( (0'|<polyline points=| + pts).fmt(vs().xplode()), 0'|style="fill:seashell; stroke:blue; stroke-width:3;" |, 0'|transform="translate(%d,%d) rotate(-18)"|.fmt(DIM,DIM), " />\n" );
} println("</svg>");</lang>
- Output:
$ zkl bbb > pentagram.svg $ cat pentagram.svg <?xml version="1.0" standalone="no" ?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/PR-SVG-20010719/DTD/svg10.dtd"> <svg height="400" width="400" style="" xmlns="http://www.w3.org/2000/svg"> <rect height="100%" width="100%" style="fill:bisque;" /> <polyline points=" 200.000, 0.000 -161.803, 117.557 " style="fill:seashell; stroke:blue; stroke-width:3;" transform="translate(200,200) rotate(-18)" /> <polyline points=" 61.803, 190.211 -161.803,-117.557 " style="fill:seashell; stroke:blue; stroke-width:3;" transform="translate(200,200) rotate(-18)" /> <polyline points="-161.803, 117.557 61.803,-190.211 " style="fill:seashell; stroke:blue; stroke-width:3;" transform="translate(200,200) rotate(-18)" /> <polyline points="-161.803,-117.557 200.000, 0.000 " style="fill:seashell; stroke:blue; stroke-width:3;" transform="translate(200,200) rotate(-18)" /> <polyline points=" 61.803,-190.211 61.803, 190.211 " style="fill:seashell; stroke:blue; stroke-width:3;" transform="translate(200,200) rotate(-18)" /> </svg>