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
Action!
<lang Action!>INCLUDE "D2:REAL.ACT" ;from the Action! Tool Kit
DEFINE REALPTR="CARD" TYPE PointR=[REALPTR x,y]
INT ARRAY SinTab=[
0 4 9 13 18 22 27 31 36 40 44 49 53 58 62 66 71 75 79 83 88 92 96 100 104 108 112 116 120 124 128 132 136 139 143 147 150 154 158 161 165 168 171 175 178 181 184 187 190 193 196 199 202 204 207 210 212 215 217 219 222 224 226 228 230 232 234 236 237 239 241 242 243 245 246 247 248 249 250 251 252 253 254 254 255 255 255 256 256 256 256]
INT FUNC Sin(INT a)
WHILE a<0 DO a==+360 OD WHILE a>360 DO a==-360 OD IF a<=90 THEN RETURN (SinTab(a)) ELSEIF a<=180 THEN RETURN (SinTab(180-a)) ELSEIF a<=270 THEN RETURN (-SinTab(a-180)) ELSE RETURN (-SinTab(360-a)) FI
RETURN (0)
INT FUNC Cos(INT a) RETURN (Sin(a-90))
PROC Det(REAL POINTER x1,y1,x2,y2,res)
REAL tmp1,tmp2
RealMult(x1,y2,tmp1) RealMult(y1,x2,tmp2) RealSub(tmp1,tmp2,res)
RETURN
BYTE FUNC IsZero(REAL POINTER a)
CHAR ARRAY s(10)
StrR(a,s) IF s(0)=1 AND s(1)='0 THEN RETURN (1) FI
RETURN (0)
BYTE FUNC Intersection(PointR POINTER p1,p2,p3,p4,res)
REAL det1,det2,dx1,dx2,dy1,dy2,nom,denom
Det(p1.x,p1.y,p2.x,p2.y,det1) Det(p3.x,p3.y,p4.x,p4.y,det2) RealSub(p1.x,p2.x,dx1) RealSub(p1.y,p2.y,dy1) RealSub(p3.x,p4.x,dx2) RealSub(p3.y,p4.y,dy2) Det(dx1,dy1,dx2,dy2,denom) IF IsZero(denom) THEN RETURN (0) FI Det(det1,dx1,det2,dx2,nom) RealDiv(nom,denom,res.x) Det(det1,dy1,det2,dy2,nom) RealDiv(nom,denom,res.y)
RETURN (1)
PROC FloodFill(BYTE x0,y0)
BYTE ARRAY xs(300),ys(300) INT first,last
first=0 last=0 xs(first)=x0 ys(first)=y0
WHILE first<=last DO x0=xs(first) y0=ys(first) first==+1 IF Locate(x0,y0)=0 THEN Plot(x0,y0) IF Locate(x0-1,y0)=0 THEN last==+1 xs(last)=x0-1 ys(last)=y0 FI IF Locate(x0+1,y0)=0 THEN last==+1 xs(last)=x0+1 ys(last)=y0 FI IF Locate(x0,y0-1)=0 THEN last==+1 xs(last)=x0 ys(last)=y0-1 FI IF Locate(x0,y0+1)=0 THEN last==+1 xs(last)=x0 ys(last)=y0+1 FI FI OD
RETURN
PROC Pentagram(INT x0,y0,r,a0 BYTE c1,c2)
INT ARRAY xs(16),ys(16) INT angle BYTE i PointR p1,p2,p3,p4,p REAL p1x,p1y,p2x,p2y,p3x,p3y,p4x,p4y,px,py p1.x=p1x p1.y=p1y p2.x=p2x p2.y=p2y p3.x=p3x p3.y=p3y p4.x=p4x p4.y=p4y p.x=px p.y=py
;outer points angle=a0 FOR i=0 TO 4 DO xs(i)=r*Sin(angle)/256+x0 ys(i)=r*Cos(angle)/256+y0 angle==+144 OD
;intersection points FOR i=0 TO 4 DO IntToReal(xs(i MOD 5),p1x) IntToReal(ys(i MOD 5),p1y) IntToReal(xs((1+i) MOD 5),p2x) IntToReal(ys((1+i) MOD 5),p2y) IntToReal(xs((2+i) MOD 5),p3x) IntToReal(ys((2+i) MOD 5),p3y) IntToReal(xs((3+i) MOD 5),p4x) IntToReal(ys((3+i) MOD 5),p4y) Intersection(p1,p2,p3,p4,p) xs(5+i)=RealToInt(px) ys(5+i)=RealToInt(py) OD
;centers of triangles FOR i=0 TO 4 DO xs(10+i)=(xs(i)+xs(5+i)+xs(5+(i+2) MOD 5))/3 ys(10+i)=(ys(i)+ys(5+i)+ys(5+(i+2) MOD 5))/3 OD
;center of pentagon xs(15)=0 ys(15)=0 FOR i=5 TO 9 DO xs(15)==+xs(i) ys(15)==+ys(i) OD xs(15)==/5 ys(15)==/5 ;draw lines COLOR=c1 FOR i=0 TO 5 DO IF i=0 THEN Plot(xs(i MOD 5),ys(i MOD 5)) ELSE DrawTo(xs(i MOD 5),ys(i MOD 5)) FI OD
;fill COLOR=c2 FOR i=10 TO 15 DO FloodFill(xs(i),ys(i)) OD
RETURN
PROC Main()
BYTE CH=$02FC
Graphics(7+16) SetColor(0,8,4) SetColor(1,8,8) SetColor(2,8,12) Pentagram(40,48,40,0,1,2) Pentagram(119,48,40,15,2,3)
DO UNTIL CH#$FF OD CH=$FF
RETURN</lang>
- Output:
Screenshot from Atari 8-bit computer
Ada
<lang Ada>with Ada.Numerics.Elementary_Functions;
with SDL.Video.Windows.Makers; with SDL.Video.Renderers.Makers; with SDL.Video.Rectangles; with SDL.Events.Events;
procedure Pentagram is
Width : constant := 600; Height : constant := 600; Offset : constant := 300.0; Radius : constant := 250.0;
use SDL.Video.Rectangles; use SDL.C;
Window : SDL.Video.Windows.Window; Renderer : SDL.Video.Renderers.Renderer; Event : SDL.Events.Events.Events;
type Node_Id is mod 5; Nodes : array (Node_Id) of Point;
procedure Calculate is use Ada.Numerics.Elementary_Functions; begin for I in Nodes'Range loop Nodes (I) := (X => int (Offset + Radius * Sin (Float (I), Cycle => 5.0)), Y => int (Offset - Radius * Cos (Float (I), Cycle => 5.0))); end loop; end Calculate;
function Orient_2D (A, B, C : Point) return int is ((B.X - A.X) * (C.Y - A.Y) - (B.Y - A.Y) * (C.X - A.X));
procedure Fill is Count : Natural; begin for Y in int (Offset - Radius) .. int (Offset + Radius) loop for X in int (Offset - Radius) .. int (Offset + Radius) loop Count := 0; for Node in Nodes'Range loop Count := Count + (if Orient_2D (Nodes (Node), Nodes (Node + 2), (X, Y)) > 0 then 1 else 0); end loop; if Count in 4 .. 5 then Renderer.Draw (Point => (X, Y)); end if; end loop; end loop; end Fill;
procedure Draw_Outline is begin for Node in Nodes'Range loop Renderer.Draw (Line => (Nodes (Node), Nodes (Node + 2))); end loop; end Draw_Outline;
procedure Wait is use type SDL.Events.Event_Types; begin loop SDL.Events.Events.Wait (Event); exit when Event.Common.Event_Type = SDL.Events.Quit; end loop; end Wait;
begin
if not SDL.Initialise (Flags => SDL.Enable_Screen) then return; end if;
SDL.Video.Windows.Makers.Create (Win => Window, Title => "Pentagram", Position => SDL.Natural_Coordinates'(X => 10, Y => 10), Size => SDL.Positive_Sizes'(Width, Height), Flags => 0); SDL.Video.Renderers.Makers.Create (Renderer, Window.Get_Surface); Renderer.Set_Draw_Colour ((0, 0, 0, 255)); Renderer.Fill (Rectangle => (0, 0, Width, Height));
Calculate; Renderer.Set_Draw_Colour ((50, 50, 150, 255)); Fill; Renderer.Set_Draw_Colour ((0, 220, 0, 255)); Draw_Outline; Window.Update_Surface;
Wait; Window.Finalize; SDL.Finalise;
end Pentagram;</lang>
Applesoft BASIC
<lang basic>100 XO = 140 110 YO = 96 120 S = 90 130 B = 7 140 F = 6 150 C = 4 200 POKE 230,64 210 HCOLOR= B 220 HPLOT 0,0 230 CALL 62454 240 A = 49232 250 I = PEEK (A + 7) + PEEK (A + 2) 260 I = PEEK (A + 5) + PEEK (A) 300 SX = S 310 SY = S 320 PI = 3.1415926535 330 E = PI * 4 340 S = PI / 1.25 350 X = SIN (0) 360 Y = COS (0) 370 HCOLOR= F 380 PX = XO + X * SX 390 PY = YO - Y * SY 400 FOR I = 0 TO E STEP S 410 X = SIN (I) 420 Y = COS (I) 430 FOR J = 0 TO SX 440 HPLOT PX,PY TO XO + X * J,YO - Y * J 450 NEXT J 460 PX = XO + X * SX 470 PY = YO - Y * SY 480 NEXT I 500 HCOLOR= C 510 PX = XO + X * SX 520 PY = YO - Y * SY 600 FOR I = S TO E STEP S 610 X = SIN (I) 620 Y = COS (I) 630 HPLOT PX,PY TO XO + X * SX,YO - Y * SY 640 HPLOT PX + 1,PY TO XO + X * SX + 1,YO - Y * SY 650 HPLOT PX,PY + 1 TO XO + X * SX,YO - Y * SY + 1 660 HPLOT PX + 1,PY + 1 TO XO + X * SX + 1,YO - Y * SY + 1 670 PX = XO + X * SX 680 PY = YO - Y * SY 690 NEXT I</lang>
AutoHotkey
<lang AutoHotkey>
- 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</lang>
C
Interactive program which takes the side lengths of the pentagram's core, it's arms and the colours for filling the background, drawing the figure and then filling it in. Requires the WinBGIm library.
<lang C>#include<graphics.h>
- include<stdio.h>
- include<math.h>
- define pi M_PI
int main(){
char colourNames[][14] = { "BLACK", "BLUE", "GREEN", "CYAN", "RED", "MAGENTA", "BROWN", "LIGHTGRAY", "DARKGRAY",
"LIGHTBLUE", "LIGHTGREEN", "LIGHTCYAN", "LIGHTRED", "LIGHTMAGENTA", "YELLOW", "WHITE" };
int stroke=0,fill=0,back=0,i;
double centerX = 300,centerY = 300,coreSide,armLength,pentaLength;
printf("Enter core pentagon side length : "); scanf("%lf",&coreSide);
printf("Enter pentagram arm length : "); scanf("%lf",&armLength);
printf("Available colours are :\n");
for(i=0;i<16;i++){ printf("%d. %s\t",i+1,colourNames[i]); if((i+1) % 3 == 0){ printf("\n"); } }
while(stroke==fill && fill==back){ printf("\nEnter three diffrenet options for stroke, fill and background : "); scanf("%d%d%d",&stroke,&fill,&back); }
pentaLength = coreSide/(2 * tan(pi/5)) + sqrt(armLength*armLength - coreSide*coreSide/4);
initwindow(2*centerX,2*centerY,"Pentagram");
setcolor(stroke-1);
setfillstyle(SOLID_FILL,back-1);
bar(0,0,2*centerX,2*centerY);
floodfill(centerX,centerY,back-1);
setfillstyle(SOLID_FILL,fill-1);
for(i=0;i<5;i++){ line(centerX + coreSide*cos(i*2*pi/5)/(2*sin(pi/5)),centerY + coreSide*sin(i*2*pi/5)/(2*sin(pi/5)),centerX + coreSide*cos((i+1)*2*pi/5)/(2*sin(pi/5)),centerY + coreSide*sin((i+1)*2*pi/5)/(2*sin(pi/5))); line(centerX + coreSide*cos(i*2*pi/5)/(2*sin(pi/5)),centerY + coreSide*sin(i*2*pi/5)/(2*sin(pi/5)),centerX + pentaLength*cos(i*2*pi/5 + pi/5),centerY + pentaLength*sin(i*2*pi/5 + pi/5)); line(centerX + coreSide*cos((i+1)*2*pi/5)/(2*sin(pi/5)),centerY + coreSide*sin((i+1)*2*pi/5)/(2*sin(pi/5)),centerX + pentaLength*cos(i*2*pi/5 + pi/5),centerY + pentaLength*sin(i*2*pi/5 + pi/5));
floodfill(centerX + coreSide*cos(i*2*pi/5 + pi/10)/(2*sin(pi/5)),centerY + coreSide*sin(i*2*pi/5 + pi/10)/(2*sin(pi/5)),stroke-1); }
floodfill(centerX,centerY,stroke-1);
getch();
closegraph(); } </lang>
Delphi
<lang Delphi> unit Main;
interface
uses
Winapi.Windows, Vcl.Graphics, Vcl.Forms, System.Math;
type
TForm1 = class(TForm) procedure FormCreate(Sender: TObject); procedure FormPaint(Sender: TObject); private procedure DrawPentagram(len, x, y: Integer; fill, stoke: TColor); { Private declarations } public { Public declarations } end;
var
Form1: TForm1; degrees144: double; degrees72: double; degrees18: double;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject); begin
ClientHeight := 640; ClientWidth := 640; degrees144 := DegToRad(144); degrees72 := DegToRad(72); degrees18 := DegToRad(18);
end;
procedure CreatePolygon(len, x, y, n: integer; ang: double; var points: TArray<TPoint>); var
angle: Double; index, i, x2, y2: Integer;
begin
angle := 0; index := 0; SetLength(points, n + 1); points[index].Create(x, y);
for i := 1 to n do begin x2 := x + round(len * cos(angle)); y2 := y + round(len * sin(-angle)); x := x2; y := y2; angle := angle - ang;
points[index].Create(x2, y2); inc(index); end; points[index].Create(points[0]);
end;
procedure TForm1.DrawPentagram(len, x, y: Integer; fill, stoke: TColor); var
points, points_internal: TArray<TPoint>; L, H: Integer;
begin
// Calc of sides for draw internal pollygon // 2H+L = len -> 2H = len - L // L = 2H*sin(36/2) (Pythagorean theorem) // L = (len-L)sin(18) // L = len*sin(18)/[1+sin(18)]
L := round(len * sin(degrees18) / (1 + sin(degrees18)));
// H = (len - L)/2
H := (len - L) div 2;
CreatePolygon(L, x + H, y, 5, degrees72, points_internal); CreatePolygon(len, x, y, 5, degrees144, points);
with Canvas, Canvas.Brush do begin with pen do begin Color := stoke; Style := psSolid; Width := 5; end; Color := fill; Polygon(points_internal); Polygon(points); end;
end;
procedure TForm1.FormPaint(Sender: TObject); begin
with Canvas, Brush do begin Style := bsSolid; Color := clWhite; // fill background with white FillRect(ClientRect); end; drawPentagram(500, 70, 250, $ED9564, clDkGray);
end;
end.</lang> form code: <lang Delphi> object Form1: TForm1
OnCreate = FormCreate OnPaint = FormPaint
end </lang>
EasyLang
<lang>xp = 10 yp = 40 linewidth 2 move xp yp while angle > -720
x = xp + cos angle * 80 y = yp + sin -angle * 80 line x y f[] &= x f[] &= y xp = x yp = y angle -= 144
. color 900 polygon f[]</lang>
Go
<lang go>package main
import (
"github.com/fogleman/gg" "math"
)
func Pentagram(x, y, r float64) []gg.Point {
points := make([]gg.Point, 5) for i := 0; i < 5; i++ { fi := float64(i) angle := 2*math.Pi*fi/5 - math.Pi/2 points[i] = gg.Point{x + r*math.Cos(angle), y + r*math.Sin(angle)} } return points
}
func main() {
points := Pentagram(320, 320, 250) dc := gg.NewContext(640, 640) dc.SetRGB(1, 1, 1) // White dc.Clear() for i := 0; i <= 5; i++ { index := (i * 2) % 5 p := points[index] dc.LineTo(p.X, p.Y) } dc.SetHexColor("#6495ED") // Cornflower Blue dc.SetFillRule(gg.FillRuleWinding) dc.FillPreserve() dc.SetRGB(0, 0, 0) // Black dc.SetLineWidth(5) dc.Stroke() dc.SavePNG("pentagram.png")
}</lang>
- Output:
The image produced is similar to that of the Java entry.
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>
IS-BASIC
<lang IS-BASIC>100 PROGRAM "Pentagra.bas" 110 OPTION ANGLE DEGREES 120 GRAPHICS HIRES 4 130 SET PALETTE BLUE,CYAN,YELLOW,BLACK 140 PLOT 640,700,ANGLE 288; 150 FOR I=1 TO 5 160 PLOT FORWARD 700,RIGHT 144; 170 NEXT 180 SET INK 3 190 SET BEAM OFF:PLOT 0,0,PAINT</lang>
J
Probably the simplest approach is:
<lang j>require'plot' plot j./2 1 o./180p_1 %~ 144*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>
jq
Works with gojq, the Go implementation of jq
This entry produces SVG output which, if placed in a file with suffix .svg, can be viewed directly in most browsers.
Notice that the size of an appropriate SVG viewBox is computed.
<lang jq># Input: {svg, minx, miny, maxx, maxy} def svg:
# viewBox = <min-x> <min-y> <width> <height> "<svg viewBox='\(.minx - 4|floor) \(.miny - 4 |floor) \(6 + .maxx - .minx|ceil) \(6 + .maxy - .miny|ceil)'", " preserveAspectRatio='xMinYmin meet'", " xmlns='http://www.w3.org/2000/svg' >", .svg, "</svg>" ;
- Input: an array of [x,y] points
def minmax:
{minx: (map(.[0])|min), miny: (map(.[1])|min), maxx: (map(.[0])|max), maxy: (map(.[1])|max)} ;
- Input: an array of [x,y] points
def Polyline($fill; $stroke; $transform):
def rnd: 1000*.|round/1000; def linearize: map( map(rnd) | join(" ") ) | join(", ");
"<polyline points='" + linearize + "'\n style='fill:\($fill); stroke: \($stroke); stroke-width:3;'" + "\n transform='\($transform)' />" ;
- Output: {minx, miny, maxx, maxy, svg}
def pentagram($dim):
(8 * (1|atan)) as $tau | 5 as $sides | [ (0, 2, 4, 1, 3, 0) | [ 0.9 * $dim * (($tau * $v / $sides) | cos), 0.9 * $dim * (($tau * $v / $sides) | sin) ] ] | minmax + {svg: Polyline("seashell"; "blue"; "rotate(-18)" )} ;
pentagram(200) | svg</lang>
- Output:
<svg viewBox='-150 -176 332 349' preserveAspectRatio='xMinYmin meet' xmlns='http://www.w3.org/2000/svg' > <polyline points='180 0, -145.623 105.801, 55.623 -171.19, 55.623 171.19, -145.623 -105.801, 180 0' style='fill:seashell; stroke: blue; stroke-width:3;' transform='rotate(-18)' /> </svg>
Julia
<lang julia>using Luxor
function drawpentagram(path::AbstractString, w::Integer=1000, h::Integer=1000)
Drawing(h, w, path) origin() setline(16)
# To get a different color border from the fill, draw twice, first with fill, then without. sethue("aqua") star(0, 0, 500, 5, 0.39, 3pi/10, :fill)
sethue("navy") verts = star(0, 0, 500, 5, 0.5, 3pi/10, vertices=true) poly([verts[i] for i in [1,5,9,3,7,1]], :stroke) finish() preview()
end
drawpentagram("data/pentagram.png")</lang>
Kotlin
<lang scala>// version 1.1.2
import java.awt.* import java.awt.geom.Path2D import javax.swing.*
class Pentagram : JPanel() {
init { preferredSize = Dimension(640, 640) background = Color.white }
private fun drawPentagram(g: Graphics2D, len: Int, x: Int, y: Int, fill: Color, stroke: Color) { var x2 = x.toDouble() var y2 = y.toDouble() var angle = 0.0 val p = Path2D.Float() p.moveTo(x2, y2) for (i in 0..4) { x2 += Math.cos(angle) * len y2 += Math.sin(-angle) * len p.lineTo(x2, y2) angle -= Math.toRadians(144.0) }
p.closePath() with(g) { color = fill fill(p) color = stroke draw(p) } }
override fun paintComponent(gg: Graphics) { super.paintComponent(gg) val g = gg as Graphics2D g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON) g.stroke = BasicStroke(5.0f, BasicStroke.CAP_ROUND, 0) drawPentagram(g, 500, 70, 250, Color(0x6495ED), Color.darkGray) }
}
fun main(args: Array<String>) {
SwingUtilities.invokeLater { val f = JFrame() with(f) { defaultCloseOperation = JFrame.EXIT_ON_CLOSE title = "Pentagram" isResizable = false add(Pentagram(), BorderLayout.CENTER) pack() setLocationRelativeTo(null) isVisible = true } }
}</lang>
Lua
Using the Bitmap class here, with an ASCII pixel representation, then extending with line()
as here, then extending with floodfill()
as here, then extending further..
<lang lua>local cos, sin, floor, pi = math.cos, math.sin, math.floor, math.pi
function Bitmap:render()
for y = 1, self.height do print(table.concat(self.pixels[y])) end
end
function Bitmap:pentagram(x, y, radius, rotation, outlcolor, fillcolor)
local function pxy(i) return x+radius*cos(i*pi*2/5+rotation), y+radius*sin(i*pi*2/5+rotation) end local x1, y1 = pxy(0) for i = 1, 5 do local x2, y2 = pxy(i*2) -- btw: pxy(i) ==> pentagon self:line(floor(x1*2), floor(y1), floor(x2*2), floor(y2), outlcolor) x1, y1 = x2, y2 end self:floodfill(floor(x*2), floor(y), fillcolor) radius = radius / 2 for i = 1, 5 do x1, y1 = pxy(i) self:floodfill(floor(x1*2), floor(y1), fillcolor) end
end
bitmap = Bitmap(40*2,40) bitmap:clear(".") bitmap:pentagram(20, 22, 20, -pi/2, "@", '+') bitmap:render()</lang>
- Output:
................................................................................ ................................................................................ .......................................@@....................................... ......................................@++@...................................... ......................................@++@...................................... .....................................@++++@..................................... ....................................@++++++@.................................... ....................................@++++++@.................................... ...................................@++++++++@................................... ...................................@++++++++@................................... ..................................@++++++++++@.................................. .................................@++++++++++++@................................. .................................@++++++++++++@................................. ................................@++++++++++++++@................................ ...............................@++++++++++++++++@............................... .@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@. ....@@@+++++++++++++++++++++++@++++++++++++++++++@+++++++++++++++++++++++++@@@.. .......@@++++++++++++++++++++@++++++++++++++++++++@++++++++++++++++++++++@@..... .........@@@+++++++++++++++++@++++++++++++++++++++@+++++++++++++++++++@@@....... ............@@@+++++++++++++@++++++++++++++++++++++@+++++++++++++++@@@.......... ...............@@++++++++++@+++++++++++++++++++++++@+++++++++++++@@............. .................@@@+++++++@++++++++++++++++++++++++@+++++++++@@@............... ....................@@@+++@++++++++++++++++++++++++++@+++++@@@.................. .......................@@+@++++++++++++++++++++++++++@+++@@..................... .........................@@@++++++++++++++++++++++++++@@@....................... ........................@+++@@@++++++++++++++++++++@@@+@........................ ........................@++++++@@+++++++++++++++@@@++++@........................ .......................@+++++++++@@@++++++++++@@++++++++@....................... ......................@+++++++++++++@@@++++@@@+++++++++++@...................... ......................@++++++++++++++++@@@@++++++++++++++@...................... .....................@++++++++++++++++@@..@@++++++++++++++@..................... ....................@++++++++++++++@@@......@@@++++++++++++@.................... ....................@+++++++++++@@@............@@@+++++++++@.................... ...................@++++++++++@@..................@@++++++++@................... ...................@+++++++@@@......................@@@+++++@................... ..................@+++++@@@............................@@@+++@.................. .................@++++@@..................................@@++@................. .................@+@@@......................................@@@................. ................@@@............................................@................ ................................................................................
Maple
<lang maple>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);</lang>
- 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/Wolfram Language
<lang mathematica>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]]]} ]</lang>
Nim
<lang nim> import libgd from math import sin, cos, degToRad
const
width = 500 height = width outerRadius = 200
proc main() =
proc calcPosition(x: int, y: int, radius: int, posAngle: float): (cint, cint) = var width = int(radius.float * sin(degToRad(posAngle))) var height = int(radius.float * cos(degToRad(posAngle))) return (cast[cint](x + width), cast[cint](y - height))
proc getPentagonPoints(startAngle = 0, radius: int): array[5, array[2, int]] = let spacingAngle = 360 / 5
var posAngle = (90 - startAngle).float
var n = 0 var points: array[5, array[2, int]] while n < 5: (points[n][0], points[n][1]) = calcPosition(250, 250, radius, posAngle) n += 1 posAngle -= spacingAngle
return points
let outerPentagon = getPentagonPoints(18, outerRadius) # rotate 18 degrees let innerPentagon = getPentagonPoints(54, int((cos(degToRad(72.0))/cos(degToRad(36.0))) * outerRadius)) # rotate 54 degrees
var pentagram: array[10, array[2, int]] var n = 0 for i in countup(0, 4): pentagram[n] = outerPentagon[i] inc(n) pentagram[n] = innerPentagon[i] inc(n)
withGd imageCreate(width, height) as img: discard img.setColor(255, 255, 255)
let black = img.setColor(0x404040) let blue = img.setColor(0x6495ed)
img.drawPolygon( points=pentagram, color=blue, fill=true, open=false)
img.setThickness(4)
img.drawPolygon( points=pentagram, color=black, fill=false, open=false)
img.drawPolygon( points=innerPentagon, color=black, fill=false, open=false)
let png_out = open("pentagram.png", fmWrite) img.writePng(png_out)
png_out.close()
main() </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
<lang perl>use SVG;
my $tau = 2 * 4*atan2(1, 1); my $dim = 200; my $sides = 5;
for $v (0, 2, 4, 1, 3, 0) {
push @vx, 0.9 * $dim * cos($tau * $v / $sides); push @vy, 0.9 * $dim * sin($tau * $v / $sides);
}
my $svg= SVG->new( width => 2*$dim, height => 2*$dim);
my $points = $svg->get_path(
x => \@vx, y => \@vy, -type => 'polyline',
);
$svg->rect (
width => "100%", height => "100%", style => { 'fill' => 'bisque' }
);
$svg->polyline (
%$points, style => { 'fill' => 'seashell', 'stroke' => 'blue', 'stroke-width' => 3, }, transform => "translate($dim,$dim) rotate(-18)"
);
open $fh, '>', 'pentagram.svg'; print $fh $svg->xmlify(-namespace=>'svg'); close $fh;</lang> Pentagram (offsite image)
Phix
Resizable and optionally rotating gui (desktop) version
You can run this online here.
-- -- demo\rosetta\Pentagram.exw -- ========================== -- -- Start/stop rotation by pressing space. Resizeable. -- ZXYV stop any rotation and orient up/down/left/right. -- with javascript_semantics include pGUI.e Ihandle dlg, canvas, timer cdCanvas cdcanvas integer rot = 0 enum FILL,BORDER constant colours = {CD_BLUE,CD_RED}, modes = {CD_FILL,CD_CLOSED_LINES} function redraw_cb(Ihandle /*ih*/, integer /*posx*/, /*posy*/) integer {w, h} = IupGetIntInt(canvas, "DRAWSIZE"), cx = floor(w/2), cy = floor(h/2), radius = floor(min(cx,cy)*0.9) cdCanvasActivate(cdcanvas) cdCanvasClear(cdcanvas) cdCanvasSetFillMode(cdcanvas, CD_WINDING) cdCanvasSetLineWidth(cdcanvas, round(radius/100)+1) for mode=FILL to BORDER do cdCanvasSetForeground(cdcanvas,colours[mode]) cdCanvasBegin(cdcanvas,modes[mode]) for a=90 to 666 by 144 do atom r = (a+rot)*CD_DEG2RAD, x = floor(radius*cos(r)+cx), y = floor(radius*sin(r)+cy) cdCanvasVertex(cdcanvas, x, y) end for cdCanvasEnd(cdcanvas) end for cdCanvasFlush(cdcanvas) return IUP_DEFAULT end function function map_cb(Ihandle ih) cdcanvas = cdCreateCanvas(CD_IUP, ih) cdCanvasSetBackground(cdcanvas, CD_PARCHMENT) return IUP_DEFAULT end function function timer_cb(Ihandle /*ih*/) rot = mod(rot+359,360) IupRedraw(canvas) return IUP_IGNORE end function function key_cb(Ihandle /*ih*/, atom c) if c=K_ESC then return IUP_CLOSE end if c = upper(c) if c=' ' then IupSetInt(timer,"RUN",not IupGetInt(timer,"RUN")) else c = find(c,"ZYXV") if c then IupSetInt(timer,"RUN",false) rot = (c-1)*90 IupRedraw(canvas) end if end if return IUP_CONTINUE end function procedure main() IupOpen() canvas = IupCanvas("RASTERSIZE=640x640") IupSetCallback(canvas, "MAP_CB", Icallback("map_cb")) IupSetCallback(canvas, "ACTION", Icallback("redraw_cb")) dlg = IupDialog(canvas,`TITLE="Pentagram"`) IupSetCallback(dlg, "KEY_CB", Icallback("key_cb")) IupShow(dlg) IupSetAttribute(canvas, "RASTERSIZE", NULL) timer = IupTimer(Icallback("timer_cb"), 80, active:=false) if platform()!=JS then IupMainLoop() IupClose() end if end procedure main()
And a quick svg version, output identical to sidef
without js constant HDR = """ <?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:black;" /> """ constant LINE = """ <polyline points="%s" style="fill:blue; stroke:white; stroke-width:3;" transform="translate(%d, %d) rotate(-18)" /> """ function pentagram(integer dim=200, sides=5) sequence v = repeat(0,sides) for i=1 to sides do atom theta = PI*2*(i-1)/5, x = cos(theta)*dim, y = sin(theta)*dim v[i] = {sprintf("%.3f",x), sprintf("%.3f",y)} end for v = append(v,v[1]) sequence q = {} for i=1 to length(v) by 2 do q &= v[i] end for for i=2 to length(v) by 2 do q &= v[i] end for string res = sprintf(HDR,dim*2) res &= sprintf(LINE,{join(q),dim,dim}) res &= "</svg>\n" return res end function puts(1,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>
Processing
<lang java> //Aamrun, 29th June 2022
size(1000,1000);
translate(width/2,height/2); rotate(3*PI/2); fill(#0000ff);
beginShape(); for(int i=0;i<10;i+=2){
vertex(450*cos(i*2*PI/5),450*sin(i*2*PI/5));
} endShape(CLOSE); </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>
Quackery
<lang Quackery>[ $ "turtleduck.qky" loadfile ] now!
[ [ 1 1
30 times [ tuck + ] swap join ] constant do ] is phi ( --> n/d )
[ 5 times
[ 2dup walk 1 5 turn 2dup walk 3 5 turn ] 2drop ] is star ( n/d --> )
[ 5 times
[ 2dup walk 2 5 turn ] 2drop ] is pentagram ( n/d --> )
turtle ' [ 79 126 229 ] fill [ 200 1 star ] 10 wide -1 10 turn 200 1 phi v* phi v* pentagram 1 10 turn</lang>
- Output:
R
Very simple approach, <lang R>p <- cbind(x = c(0, 1, 2,-0.5 , 2.5 ,0),
y = c(0, 1, 0,0.6, 0.6,0))
plot(p) lines(p)</lang>
Using circle equation
A better more accurate approach utilising equation of a circle using polar coordinates.[1] 5 points are required to draw a pentagram. a circle with centre coordinates x=10 and y=10 with radius 10 was chosen for this example. In order to find 5 equal points circle needs to be divided by 5 i.e 360/5 = 72 each point on the circumference is 72 degrees apart, 5 points on the circles circumference are calculated and than plotted and line drawn in-between to produce pentagram <lang rsplus>#Circle equation
- x = r*cos(angle) + centre_x
- y = r*sin(angle) + centre_y
- centre points
centre_x = 10 centre_y = 10
- radius
r = 10
deg2rad <- function(d){
return((d*pi)/180)
} #Converts Degrees to radians X_coord <- function(r=10,centre_x=10,angle) #Finds Xcoordinate on the circumference {
return(r*cos(deg2rad(angle)) + centre_x)
} Y_coord <- function(r=10,centre_y=10,angle) #Finds Ycoordinate on the circumference {
return(r*sin(deg2rad(angle)) + centre_x)
}
- series of angles after dividing the circle in to 5
angles <- list() for(i in 1:5) {
angles[i] <- 72*i
} angles <- unlist(angles) #flattening the list
for(i in seq_along(angles)){
print(i) print(angles[i]) if(i == 1) { coordinates <- cbind(c( x = X_coord(angle = angles[i]), y = Y_coord(angle = angles[i])) ) } else{ coordinates <- cbind(coordinates,cbind(c( x = X_coord(angle = angles[i]), y = Y_coord(angle = angles[i])))) }
} plot(xlim = c(0,30), ylim = c(0,30),x = coordinates[1,], y=coordinates[2,])
polygon(x = coordinates[1,c(1,3,5,2,4,1)],
y=coordinates[2,c(1,3,5,2,4,1)], col = "#1b98e0", border = "red", lwd = 5)</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>
Raku
(formerly Perl 6)
Generate an SVG file to STDOUT. Redirect to a file to capture and display it. <lang perl6>use SVG;
constant $dim = 200; constant $sides = 5;
my @vertices = map { 0.9 * $dim * cis($_ * τ / $sides) }, ^$sides;
my @points = map |*.reals.fmt("%0.3f"),
flat @vertices[0, 2 ... *], @vertices[1, 3 ... *], @vertices[0];
say SVG.serialize(
svg => [ :width($dim*2), :height($dim*2), :rect[:width<100%>, :height<100%>, :style<fill:bisque;>], :polyline[ :points(@points.join: ','), :style("stroke:blue; stroke-width:3; fill:seashell;"), :transform("translate($dim,$dim) rotate(-90)") ], ],
);</lang> See Pentagram (offsite svg image)
Ever wondered what a regular 7 sided star looks like? Change $sides to 7 and re-run. See Heptagram
Red
<lang red>Red [ Source: https://github.com/vazub/rosetta-red Tabs: 4 Needs: 'View ]
canvas: 500x500 center: as-pair canvas/x / 2 canvas/y / 2 radius: 200
points: collect [ repeat vertex 10 [ angle: vertex * 36 + 18 ;-- +18 is required for pentagram rotation either vertex // 2 = 1 [ keep as-pair (cosine angle) * radius + center/x (sine angle) * radius + center/y ][ keep as-pair (cosine angle) * radius * 0.382 + center/x (sine angle) * radius * 0.382 + center/y ] ] ]
view [ title "Pentagram" base canvas white draw compose/deep [ fill-pen mint polygon (points) line-width 3 line (points/1) (points/5) (points/9) (points/3) (points/7) (points/1) ] ] </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>
Ring
<lang ring>
- Project : Pentagram
load "guilib.ring"
paint = null
new qapp
{ win1 = new qwidget() { setwindowtitle("Pentagram") setgeometry(100,100,500,600) label1 = new qlabel(win1) { setgeometry(10,10,400,400) settext("") } new qpushbutton(win1) { setgeometry(150,500,100,30) settext("draw") setclickevent("draw()") } show() } exec() }
func draw
p1 = new qpicture() color = new qcolor() { setrgb(0,0,255,255) } pen = new qpen() { setcolor(color) setwidth(5) } paint = new qpainter() { begin(p1) setpen(pen)
nn = 165 cx = 800 cy = 600 phi = 54
color = new qcolor() color.setrgb(0, 0, 255,255) mybrush = new qbrush() {setstyle(1) setcolor(color)} setbrush(mybrush)
for n = 1 to 5 theta = fabs(180-144-phi)
p1x = floor(cx + nn * cos(phi * 0.01745329252)) p1y = floor(cy + nn * sin(phi * 0.01745329252)) p2x = floor(cx - nn * cos(theta * 0.01745329252)) p2y = floor(cy - nn * sin(theta * 0.01745329252)) phi+= 72 drawpolygon([[p1x,p1y],[cx,cy],[p2x,p2y]],0)
next endpaint() } label1 { setpicture(p1) show() } return
</lang> Output:
https://www.dropbox.com/s/znbcsoatlc00n4w/Pentagram.jpg?dl=0
Scala
Java Swing Interoperability
<lang Scala>import java.awt._ import java.awt.geom.Path2D
import javax.swing._
object Pentagram extends App {
SwingUtilities.invokeLater(() => new JFrame("Pentagram") {
class Pentagram extends JPanel { setPreferredSize(new Dimension(640, 640)) setBackground(Color.white) final private val degrees144 = Math.toRadians(144)
override def paintComponent(gg: Graphics): Unit = { val g = gg.asInstanceOf[Graphics2D]
def drawPentagram(g: Graphics2D, x: Int, y: Int, fill: Color): Unit = { var (_x, _y, angle) = (x, y, 0.0) val p = new Path2D.Float p.moveTo(_x, _y) for (i <- 0 until 5) { val (x2, y2) = (_x + (Math.cos(angle) * 500).toInt, _y + (Math.sin(-angle) * 500).toInt) p.lineTo(x2, y2) _x = x2 _y = y2 angle -= degrees144 } p.closePath() g.setColor(fill) g.fill(p) g.setColor(Color.darkGray) g.draw(p) }
super.paintComponent(gg) g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON) g.setStroke(new BasicStroke(5, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)) drawPentagram(g, 70, 250, new Color(0x6495ED)) } }
add(new Pentagram, BorderLayout.CENTER) pack() setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE) setLocationRelativeTo(null) setResizable(false) setVisible(true) } )
}</lang>
Sidef
Generates a SVG image to STDOUT. <lang ruby>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()</lang>
- 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>
SPL
<lang spl>mx,my = #.scrsize() xc = mx/2 yc = my/2 mr = #.min(mx,my)/3
- .angle(#.degrees)
- .drawcolor(1,0,0)
- .drawsize(10)
> r, mr..0,-1
#.drawline(xc,yc-r,xc,yc-r) > a, 54..630,144 #.drawline(r*#.cos(a)+xc,r*#.sin(a)+yc) < #.drawcolor(1,1,0) #.drawsize(1)
<</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>
VBA
<lang vb>Sub pentagram()
With ActiveSheet.Shapes.AddShape(msoShape5pointStar, 10, 10, 400, 400) .Fill.ForeColor.RGB = RGB(255, 0, 0) .Line.Weight = 3 .Line.ForeColor.RGB = RGB(0, 0, 255) End With
End Sub</lang>
Wren
<lang ecmascript>import "graphics" for Canvas, Color, Point import "dome" for Window
class Game {
static init() { Window.title = "Pentagram" var width = 640 var height = 640 Window.resize(width, height) Canvas.resize(width, height) Canvas.cls(Color.white) var col = Color.hex("#6495ed") // cornflower blue for (i in 1..240) pentagram(320, 320, i, col) for (i in 241..250) pentagram(320, 320, i, Color.black) }
static update() {}
static draw(alpha) {}
static pentagram(x, y, r, col) { var points = List.filled(5, null) for (i in 0..4) { var angle = 2*Num.pi*i/5 - Num.pi/2 points[i] = Point.new(x + r*angle.cos, y + r*angle.sin) } var prev = points[0] for (i in 1..5) { var index = (i * 2) % 5 var curr = points[index] Canvas.line(prev.x, prev.y, curr.x, curr.y, col) prev = curr } }
}</lang>
XPL0
<lang XPL0>proc FillArea(X, Y, C0, C); \Replace area colored C0 with color C int X, Y, \starting coordinate for flood fill algorithm
C0, C; \initial color, and color to replace it with
def S=8000; \size of queue (must be an even number) int Q(S), \queue (FIFO)
F, E; \fill and empty indexes
proc EnQ(X, Y); \Enqueue coordinate int X, Y; [Q(F):= X; F:= F+1; Q(F):= Y; F:= F+1; if F >= S then F:= 0; ]; \EnQ
proc DeQ; \Dequeue coordinate [X:= Q(E); E:= E+1; Y:= Q(E); E:= E+1; if E >= S then E:= 0; ]; \DeQ
[if C0 = C then return; F:= 0; E:= 0; EnQ(X, Y); while E # F do
[DeQ; if ReadPix(X, Y) = C0 then [Point(X, Y, C); EnQ(X+1, Y); \enqueue adjacent pixels EnQ(X-1, Y); EnQ(X, Y+1); EnQ(X, Y-1); ]; ];
]; \FillArea
def Size = 200.; def Pi = 3.141592654; def Deg144 = 4.*Pi/5.; int X, Y, N; [SetVid($12); \set 640x480x4 VGA graphics for Y:= 0 to 480-1 do \fill screen
[Move(0, Y); Line(640-1, Y, $F\white\)];
for N:= 0 to 5 do \draw pentagram
[X:= fix(Size*Sin(float(N)*Deg144)); Y:= fix(Size*Cos(float(N)*Deg144)); if N = 0 then Move(X+320, 240-Y) else Line(X+320, 240-Y, 4\red\); ];
FillArea(0, 0, $F, 1); \replace white (F) with blue (1) ]</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].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>");</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>
Until local image uploading is re-enabled, see this image.
- Programming Tasks
- Solutions by Programming Task
- Action!
- Action! Tool Kit
- Ada
- SDLAda
- Applesoft BASIC
- AutoHotkey
- C
- Delphi
- Winapi.Windows
- Vcl.Graphics
- Vcl.Forms
- System.Math
- EasyLang
- Go
- Go Graphics
- Haskell
- IS-BASIC
- J
- Java
- Jq
- Julia
- Kotlin
- Lua
- Maple
- Mathematica
- Wolfram Language
- Nim
- Nim-libgd
- OoRexx
- Perl
- Phix
- Phix/pGUI
- Phix/online
- PostScript
- Processing
- Python
- Quackery
- R
- Using circle equation
- Racket
- Raku
- Red
- REXX
- Ring
- Scala
- Sidef
- SPL
- Tcl
- VBA
- Wren
- DOME
- XPL0
- Zkl
- The background and foreground colors are the same. examples needing attention
- Examples needing attention
- Geometry