Pentagram

From Rosetta Code
Task
Pentagram
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



AutoHotkey[edit]

Pentagram Java.png
 
#Include Gdip.ahk ; https://autohotkey.com/boards/viewtopic.php?f=6&t=6517
Width :=A_ScreenWidth, Height := A_ScreenHeight
Gui, 1: +E0x20 +Caption +E0x80000 +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs
Gui, 1: Show, NA
hwnd1 := WinExist()
OnExit, Exit
 
If !pToken := Gdip_Startup()
{
MsgBox, 48, gdiplus error!, Gdiplus failed to start.
. Please ensure you have gdiplus on your system
ExitApp
}
 
hbm := CreateDIBSection(Width, Height)
hdc := CreateCompatibleDC()
obm := SelectObject(hdc, hbm)
G := Gdip_GraphicsFromHDC(hdc)
Gdip_SetSmoothingMode(G, 4)
pBrush := Gdip_BrushCreateSolid(0xFF6495ED)
pPen := Gdip_CreatePen(0xff000000, 3)
 
;---------------------------------
LL := 165
Cx := Floor(A_ScreenWidth/2)
Cy := Floor(A_ScreenHeight/2)
phi := 54
;---------------------------------
loop, 5
{
theta := abs(180-144-phi)
p1x := Floor(Cx + LL * Cos(phi * 0.01745329252))
p1y := Floor(Cy + LL * Sin(phi * 0.01745329252))
p2x := Floor(Cx - LL * Cos(theta * 0.01745329252))
p2y := Floor(Cy - LL * Sin(theta * 0.01745329252))
phi+= 72
Gdip_FillPolygon(G, pBrush, p1x "," p1y "|" Cx "," Cy "|" p2x "," p2y)
}
loop, 5
{
theta := abs(180-144-phi)
p1x := Floor(Cx + LL * Cos(phi * 0.01745329252))
p1y := Floor(Cy + LL * Sin(phi * 0.01745329252))
p2x := Floor(Cx - LL * Cos(theta * 0.01745329252))
p2y := Floor(Cy - LL * Sin(theta * 0.01745329252))
phi+= 72
Gdip_DrawLines(G, pPen, p1x "," p1y "|" p2x "," p2y ) ; "|" Cx "," Cy )
}
UpdateLayeredWindow(hwnd1, hdc, 0, 0, Width, Height)
Gdip_DeleteBrush(pBrush)
SelectObject(hdc, obm)
DeleteObject(hbm)
DeleteDC(hdc)
Gdip_DeleteGraphics(G)
return
;----------------------------------------------------------------------
Esc::
Exit:
Gdip_Shutdown(pToken)
ExitApp
Return

Haskell[edit]

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.

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

J[edit]

Probably the simplest approach is:

require'plot'
plot j./2 1 o./180p_1 %~ 72*i. 6

This will give a pentagram with a blue border and a white interior.

Java[edit]

Pentagram Java.png
Works with: Java version 8
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);
});
}
}

Maple[edit]

with(geometry):
RegularStarPolygon(middle, 5/2, point(c, 0, 0), 1):
v := [seq(coordinates(i), i in DefinedAs(middle))]:
pentagram := plottools[rotate](plottools[polygon](v), Pi/2):
plots[display](pentagram, colour = yellow, axes = none);
Output:

Note: Plot shown below is generated using interface(plotdevice = char);

                                       C                                      
                                      C C                                     
                                     C   C                                    
                                    C     C                                   
                                   C       C                                  
                                 CC         CC                                
                                C             C                               
                               C               C                              
   CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC  
      CCCC                   C                   C                   CCCC     
          CCCCC             C                     C             CCCCC         
               CCCC         C                     C         CCCC              
                   CCCCC   C                       C   CCCCC                  
                        CCCC                       CCCC                       
                         C  CCCCC             CCCCC  C                        
                        C        CCCC     CCCC        C                       
                      CC             CCCCC             CC                     
                     C           CCCCC   CCCCC           C                    
                    C        CCCC             CCCC        C                   
                   C    CCCCC                     CCCCC    C                  
                  C CCCC                               CCCC C                 
                 CCC                                       CCC               

Mathematica[edit]

 
Graphics[{
EdgeForm[Directive[Thickness[0.01], RGBColor[0, 0, 1]]],(*Edge coloring*)
RGBColor[0.5, 0.5, .50], (*Fill coloring*)
Polygon[AnglePath[Table[6 Pi/5, 5]]]}
]
 

ooRexx[edit]

/* 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

Perl 6[edit]

Works with: rakudo version 2016-01

Generate an SVG file to STDOUT. Redirect to a file to capture and display it.

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="[email protected][[email protected], 0, 1].fmt("%0.3f")}"
style="fill:seashell; stroke:blue; stroke-width:3;"
transform="translate($dim, $dim) rotate(-18)" />
STOP
}

See Pentagram

PostScript[edit]

%!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

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...

%!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

Python[edit]

Works with: Python version 3.4.1
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()

Racket[edit]

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

REXX[edit]

Translation of: ooRexx
/* 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

Sidef[edit]

Translation of: Perl 6

Generates a SVG image to STDOUT.

func pentagram(dim=200, sides=5) {
var pentagram = <<-EOT
<?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:black;" />
EOT
 
func cis(x) {
cos(x) + sin(x).i
}
 
func pline(q) {
<<-EOT
<polyline points="#{[q..., q[0], q[1]].map{|n| '%0.3f' % n }.join(' ')}"
style="fill:blue; stroke:white; stroke-width:3;"
transform="translate(#{dim}, #{dim}) rotate(-18)" />
EOT
}
 
var v = sides.range.map {|k| 0.9 * dim * cis(k * Num.tau / sides) }
pentagram += pline([v[range(0, v.end, 2)], v[range(1, v.end, 2)]].map{.reals})
pentagram += '</svg>'
 
return pentagram
}
 
say pentagram()
Output:
<?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:black;" />
<polyline points="180.000 0.000 -145.623 105.801 55.623 -171.190 55.623 171.190 -145.623 -105.801 180.000 0.000"
style="fill:blue; stroke:white; stroke-width:3;"
transform="translate(200, 200) rotate(-18)" />
</svg>

Tcl[edit]

This implementation draws a simple pentagram on a Canvas widget.

Works with: Tcl version 8.6
 
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!
 

zkl[edit]

Translation of: Perl 6

Generate an SVG file to STDOUT. Redirect to a file to capture and display it.

const DIM=200, SIDES=5, A=360/SIDES, R=DIM.toFloat();
vs:=[0.0..360-A,A].apply("toRad"); // 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) }); //( (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>");
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>

Until local image uploading is re-enabled, see this image.