Skip to content

Commit 6da6122

Browse files
committed
Initial commit
0 parents  commit 6da6122

File tree

153 files changed

+1819666
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

153 files changed

+1819666
-0
lines changed

.DS_Store

18 KB
Binary file not shown.

.gitattributes

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Auto detect text files and perform LF normalization
2+
* text=auto

C/Smalls_SVG.c

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
// By and copyright Julian D. A. Wiseman of www.jdawiseman.com, April 2025
2+
// Released under GNU General Public License, Version 3, https://www.gnu.org/licenses/gpl-3.0.txt
3+
// smalls_SVG.c, in PenroseC
4+
5+
#include "penrose.h"
6+
7+
#define almostZero 5E-10 // consistent with %0.9lf
8+
9+
char * svgTransform(char * const str, double const x, double const y, double const angDeg, short int angMod )
10+
{
11+
double angDegNew = angDeg;
12+
int8_t i;
13+
extern char scratchString[];
14+
15+
for( i = 0 ; i < 5 ; i++ ) // Finitely many in case a DBL_MAX has somehow crept in. Shouldn't happen, but...
16+
if( angDegNew < 0 )
17+
angDegNew += angMod;
18+
else
19+
break;
20+
21+
for( i = 0 ; i < 5 ; i++ )
22+
if( angDegNew + almostZero >= angMod )
23+
angDegNew -= angMod;
24+
else
25+
break;
26+
27+
28+
// Six cases: {Ang != 0, Ang == 0} * {Y != 0, Y == 0 but X != 0, both == 0}
29+
if( fabs(y) <= almostZero )
30+
{
31+
if( fabs(angDegNew) <= almostZero )
32+
{
33+
if( fabs(x) <= almostZero )
34+
str[0] = 0;
35+
else
36+
sprintf(str, " transform='translate(%0.9lf)'", x);
37+
} // angDegNew == 0
38+
else
39+
{
40+
if( fabs(x) <= almostZero )
41+
sprintf(str, " transform='rotate(%0.9lf)'", angDegNew);
42+
else
43+
sprintf(str, " transform='translate(%0.9lf) rotate(%0.9lf)'", x, angDegNew);
44+
} // angDegNew != 0
45+
} // y == 0
46+
else
47+
{
48+
if( fabs(angDegNew) <= almostZero )
49+
sprintf(str, " transform='translate(%0.9lf,%0.9lf)'", x, y);
50+
else
51+
sprintf(str, " transform='translate(%0.9lf,%0.9lf) rotate(%0.9lf)'", x, y, angDegNew);
52+
} // y != 0
53+
54+
stringClean(scratchString);
55+
return str;
56+
} // svgTransform()
57+
58+
59+
60+
// A is 'long' string; B is 'short' string.
61+
void exportColourSVG(char * const strA, char * const strB, bool * const isWhiteP, const Physique ph, const bool pathClosed, const long int pathLength, const bool pointy)
62+
{
63+
strA[0] = 0; // default
64+
strB[0] = 0; // default
65+
*isWhiteP = false; // default
66+
67+
if( Thin == ph )
68+
{
69+
sprintf(strB, "#CCC");
70+
sprintf(strA, "fill='%s' opacity='1'> <!-- Thins: light grey -->", strB);
71+
return ;
72+
}
73+
74+
if( pathClosed ) // Fat and closed
75+
{
76+
if( pathLength == 5 && pointy )
77+
{
78+
sprintf(strB, "#9F9");
79+
sprintf(strA, "fill='%s' opacity='1'> <!-- Fats, closed PathLength=5 pointy: light green -->", strB);
80+
return ;
81+
} // 5 pointy
82+
83+
if( pathLength == 5 ) // so round
84+
{
85+
*isWhiteP = true;
86+
sprintf(strB, "#FFF");
87+
sprintf(strA, "fill='%s' opacity='1'> <!-- Fats, closed PathLength=5 round: white -->", strB);
88+
return ;
89+
} // 5 round
90+
91+
if( pathLength == 15 )
92+
{
93+
sprintf(strB, "#004C00");
94+
sprintf(strA, "fill='%s' opacity='1'> <!-- Fats, closed, PathLength=15: very dark green -->", strB);
95+
return ;
96+
} // 15 closed
97+
98+
if( pathLength == 25 )
99+
{
100+
sprintf(strB, "#009");
101+
sprintf(strA, "fill='%s' opacity='1'> <!-- Fats, closed, PathLength=25: dark blue -->", strB);
102+
return ;
103+
} // 25 closed
104+
105+
if( pathLength == 55 )
106+
{
107+
sprintf(strB, "#00F");
108+
sprintf(strA, "fill='%s' opacity='1'> <!-- Fats, closed, PathLength=55: blue -->", strB);
109+
return ;
110+
} // 55 closed
111+
112+
if( pathLength == 105 )
113+
{
114+
sprintf(strB, "#F6F");
115+
sprintf(strA, "fill='%s' opacity='1'> <!-- Fats, closed, PathLength=105: pink -->", strB);
116+
return ;
117+
} // 105 closed
118+
119+
if( pathLength == 215 )
120+
{
121+
sprintf(strB, "#600000");
122+
sprintf(strA, "fill='%s' opacity='1'> <!-- Fats, closed, PathLength=215: maroon -->", strB);
123+
return ;
124+
} // 215 closed
125+
126+
if( pathLength == 425 )
127+
{
128+
sprintf(strB, "#090");
129+
sprintf(strA, "fill='%s' opacity='1'> <!-- Fats, closed, PathLength=425: dark green -->", strB);
130+
return ;
131+
} // 425 closed
132+
133+
if( pathLength == 855 )
134+
{
135+
sprintf(strB, "#09F");
136+
sprintf(strA, "fill='%s' opacity='1'> <!-- Fats, closed, PathLength=855: light blue -->", strB);
137+
return ;
138+
} // 855 closed
139+
140+
if( pathLength == 1705 )
141+
{
142+
sprintf(strB, "#F60");
143+
sprintf(strA, "fill='%s' opacity='1'> <!-- Fats, closed, PathLength=1705: orange -->", strB);
144+
return ;
145+
} // 1705 closed
146+
147+
if( pathLength >= 3415 )
148+
{
149+
sprintf(strB, "#191919");
150+
sprintf(strA, "fill='%s' opacity='1'> <!-- Fats, closed, PathLength>=3415: very dark grey -->", strB);
151+
return ;
152+
} // >=3415 closed
153+
} // Closed
154+
else
155+
{
156+
if( pathLength >= 84 )
157+
{
158+
sprintf(strB, "#%2X0000", 128 + ( 73 * ((int)floor(log2(pathLength) + 0.5)) ) % 128 ); // The +0.5 distinguishes the likes of 128 and 253.
159+
sprintf(strA, "fill='%s' opacity='1'> <!-- Fats, open, PathLength=%li: shades of red -->", strB, pathLength);
160+
return ;
161+
} // Open and long
162+
163+
if( pathLength == 3 || pathLength == 4 )
164+
{
165+
sprintf(strB, "#333");
166+
sprintf(strA, "fill='%s' opacity='1' stroke='#000'> <!-- Fats, open, PathLength=%li: dark grey, to give whole tiling appearance of a serrated edge -->", strB, pathLength);
167+
return ;
168+
} // Open, 3 or 4, to give whole tiling appearance ofa serrated edge.
169+
170+
*isWhiteP = true;
171+
sprintf(strB, "#FFF");
172+
sprintf(strA, "fill='%s' opacity='1'> <!-- Fats, open PathLength=%li: white -->", strB, pathLength);
173+
return ; // Open, neither long nor 3 nor 4, boringly white.
174+
175+
} // Open
176+
} // exportColourSVG()
177+
178+

C/controls.c

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
// By and copyright Julian D. A. Wiseman of www.jdawiseman.com, April 2025
2+
// Released under GNU General Public License, Version 3, https://www.gnu.org/licenses/gpl-3.0.txt
3+
// main.c, in PenroseC
4+
5+
#include "penrose.h"
6+
7+
// Change to match your directory structure, and location of applications.
8+
static char const filePath_staticConst[] = "/Users/JDAW/Documents/outputPenrose/";
9+
10+
#define AnyPostProcessing false
11+
12+
// Location and name of application should match your machine's arrangement. Or can become empty do-nothing.
13+
void execute_SVG_PostProcessing(
14+
const Tiling * const tlngP,
15+
const unsigned long int numLinesThisFile,
16+
const unsigned long long int numCharsThisFile,
17+
const char * const fileName,
18+
ExportFormat const ef
19+
)
20+
{
21+
extern char scratchString[];
22+
if( AnyPostProcessing )
23+
{
24+
if( ef == SVG_arcs || numCharsThisFile < 10737418240 ) // 10 MiB. Limit very different for arcs and rhombii. https://issues.chromium.org/issues/390969197
25+
{
26+
// Change next line to invoke your preferred browser.
27+
sprintf(scratchString, "open -a '/Applications/Google Chrome.app' 'file://%s'", fileName);
28+
system(scratchString); // In general, system() can be a serious security risk. If concerned, delete.
29+
} // Not too big
30+
} // AnyPostProcessing
31+
} // execute_SVG_PostProcessing()
32+
33+
// Location and name of application should match your machine's arrangement. Or can become empty do-nothing.
34+
void execute_PostScript_PostProcessing(
35+
const Tiling * const tlngP,
36+
const unsigned long int numLinesThisFile,
37+
const unsigned long long int numCharsThisFile,
38+
const char * const fileName,
39+
ExportFormat const ef
40+
)
41+
{
42+
extern char scratchString[];
43+
if( AnyPostProcessing )
44+
{
45+
// Change next line to invoke your preferred PS-to-PDF application, likely either Distiller or GhostScript.
46+
sprintf(scratchString, "open -a '/Applications/Adobe_Acrobat_2020_20240514/Acrobat Distiller.app' '%s'", fileName);
47+
system(scratchString); // In general, system() can be a serious security risk. If concerned, delete.
48+
} // AnyPostProcessing
49+
} // execute_PostScript_PostProcessing()
50+
51+
52+
53+
// User-changeable function: what should be output? Can matter because output can be very big.
54+
bool exportQ(ExportWhat const exprtWhat, ExportFormat const exportFormat, const Tiling * const tlngP, const unsigned long int numLinesThisFile)
55+
{
56+
long int const ExcelMaxNumRows = 1048576; // Maximum number of rows in Excel versions >=2013.
57+
58+
switch(exportFormat)
59+
{
60+
case JSON:
61+
return( true );
62+
63+
case PS_data:
64+
return( tlngP->tilingId == tlngP->numTilings - 1 );
65+
66+
case SVG_rhomb:
67+
case SVG_arcs:
68+
return( tlngP->tilingId >= -1 ); // Null condition, always true
69+
70+
case PS_arcs:
71+
case PS_rhomb:
72+
return( tlngP->tilingId >= -1 ); // Null condition, always true
73+
74+
case TSV:
75+
switch(exprtWhat)
76+
{
77+
case Anything:
78+
return( 18 + numLinesThisFile < ExcelMaxNumRows );
79+
case pathStats:
80+
return( 10 + numLinesThisFile + tlngP->numPathStats < ExcelMaxNumRows );
81+
case Paths:
82+
return( 10 + numLinesThisFile + tlngP->numPathsClosed + tlngP->numPathsOpen < ExcelMaxNumRows - 10240 ); // Leaving space for subsequent pathStats
83+
case Rhombii:
84+
return( 10 + numLinesThisFile + tlngP->numFats + tlngP->numThins < ExcelMaxNumRows - 10240 ); // Leaving space for subsequent pathStats
85+
} // switch(exprtWhat)
86+
break; // Redundant
87+
88+
} // switch(exportFormat)
89+
90+
return false; // Redundant
91+
} // exportQ()
92+
93+
94+
95+
// This test was used to make documentation that shows effect of holesFill().
96+
// But in production, want holesFill() always.
97+
bool holesFillQ(const Tiling * const tlngP)
98+
{
99+
return true; // Example alternative: return (tlngP->tilingId <= 2);
100+
} // holesFillQ()
101+
102+
103+
104+
// These can be changed to show, in SVG, only a subset of the rhombii.
105+
// Comments have example, as used to make image in documentation.
106+
// These y values are as generated by C code; SVG's y values are -1* these.
107+
const double svg_toPaint_xMin(const Tiling * const tlngP) {return -999999;} // -0.09830056, from tilingId==10, paths 13 and 30, + edgeLength * Sin(18)
108+
const double svg_toPaint_yMin(const Tiling * const tlngP) {return -999999;} // +0.46449333, from tilingId==10, paths 13 and 30, + edgeLength * Sin(36)
109+
const double svg_toPaint_xMax(const Tiling * const tlngP) {return +999999;} // +1.27553483, from tilingId==10, paths 13 and 30, - edgeLength * Sin(18)
110+
const double svg_toPaint_yMax(const Tiling * const tlngP) {return +999999;} // +1.62459848, from tilingId==10, paths 13 and 30, - edgeLength * Sin(36)
111+
const double svg_displayWidth(const Tiling * const tlngP) {return 960;} // GitHub seems to use a 1012px column. This that, less a little wiggle room for margin and padding.
112+
const double svg_strokeWidth(const Tiling * const tlngP) {return tlngP->edgeLength / 16;}
113+
114+
115+
const long int svg_arcs_longestPathToBeColoured(void)
116+
{
117+
// If enlarging this might need to add more colours to "<style>" in tiling_export_PaintArcsSVG().
118+
return 215;
119+
} // svg_arcs_longestPathToBeColoured
120+
121+
122+
123+
XY wantedPostScriptCentre(void)
124+
{
125+
return (XY){.x=0.202, .y=0.026};
126+
} // wantedPostScriptCentre()
127+
double wantedPostScriptAspect(void)
128+
{
129+
return 1.44; // Portrait A3, less 8.73mm margins all round: (420 - 2*8.73) / (297 - 2*8.73) ~= 1.44001
130+
} // wantedPostScriptAspect()
131+
132+
bool rhombus_keep(
133+
const Tiling * const tlngP, Physique const physique,
134+
double const xNorth, double const yNorth, double const xSouth, double const ySouth
135+
)
136+
{
137+
return true;
138+
// Example alternative:
139+
// return xNorth > (-1 * tlngP->edgeLength);
140+
} // rhombus_keep
141+
142+
143+
144+
// Wrappers
145+
const char * filePath(void)
146+
{
147+
return filePath_staticConst;
148+
} // filePath()

0 commit comments

Comments
 (0)