Electronic – Drawing with a triangular aperture in Gerber

gerberpcb

So, I`d like to output a rounded equilateral triangle in Gerber format.

The first method I tried was to pick a large triangular aperture (%ADD11P,8X3*%, that is) and draw a small closed arc, a.k.a. circle, with it:

%FSLAX26Y26*%
%MOMM*%
G01*
%LPD*%
%ADD10C,1*%
%ADD11P,8X3*%
D11*
X00000000Y00000000D02*
G03*
G75*
I01000000J01000000D01*
M02*

However, the reference Gerber viewer throws a rather peculiar error while trying to interpret that file:

Arc with a non-circular aperture found. This is invalid.

Okay, I thought, but I can still approximate a circle with lines, right? Let`s try drawing a line:

%FSLAX26Y26*%
%MOMM*%
G01*
%LPD*%
%ADD10C,1*%
%ADD11P,8X3*%
D11*
X00000000Y00000000D02*
X11000000Y07000000D01*
M02*

And again, the reference app doesn`t seem to like what I`m trying to do:

Draw with an invalid aperture 11 emulated. Review resulting image.

And only if I correct my aperture definition to become a diamond instead of a triangle (%ADD11P,8X4*%) no errors get thrown.

Am I doing something wrong? Is drawing arcs or lines with triangular apertures documented as incorrect in the standard somewhere?

Naturally, I know I can compute 3 points and draw 3 segments between them using a circle and then fill the interior with a polygon, but I`d really like to avoid that. The task this one is a part of implies drawing multiple triangles with different orientations which can easily be set using the aperture angle parameter.

…Well, preliminary solution found:

%FSLAX26Y26*%
%MOMM*%
G01*
%LPD*%
%AM_my_own_triangle*
$5=$1*
$6=$2x$1*
$7=0.8660254x$5*
4,1,3,$5,0,-0.5x($5+$6),$7,-0.5x($5+$6),-$7,$5,0,$3+$4*
4,1,3,$5,0,-0.5x($5+$6),$7,-0.5x($5+$6),-$7,$5,0,$3+$4+120*
4,1,3,$5,0,-0.5x($5+$6),$7,-0.5x($5+$6),-$7,$5,0,$3+$4+240*
1,1,$6,$5,0,$3+$4*
1,1,$6,$5,0,$3+$4+120*
1,1,$6,$5,0,$3+$4+240*%
%ADD10_my_own_triangle,100x0.1x0x0*%
D10*X00000000Y00000000D03*
M02*

Here I make extensive use of the so-called Aperture Macro definitions. AMs can be rotated independently, see $3+$4+*, and support variables in arithmetic expressions.

This seems to be it, so if in a week`s time nothing less inelegant appears in answers, I`m going to answer the question myself.

Best Answer

Okay, here are the two solutions: the «short» and the «compatible» (for nobody except the official Gerber viewer seems to interpret the «short» one correctly).

Short

%FSLAX26Y26*%
%MOMM*%
G01*
%LPD*%
%AM_my_own_triangle*
$5=$1*
$6=$2x$1*
$7=0.8660254x$5*
4,1,3,$5,0,-0.5x($5+$6),$7,-0.5x($5+$6),-$7,$5,0,$3+$4*
4,1,3,$5,0,-0.5x($5+$6),$7,-0.5x($5+$6),-$7,$5,0,$3+$4+120*
4,1,3,$5,0,-0.5x($5+$6),$7,-0.5x($5+$6),-$7,$5,0,$3+$4+240*
1,1,$6,$5,0,$3+$4*
1,1,$6,$5,0,$3+$4+120*
1,1,$6,$5,0,$3+$4+240*%
%ADD10_my_own_triangle,100x0.1x0x0*%
D10*X00000000Y00000000D03*
M02*

Here, the so-called variable Aperture Macros are being used. Literally not a single third-party Gerber viewer I tried, be it online or installable, had support for AMs that contain variables.

Compatible

My suspicions have turned out to be true. For your Gerber files to be understood by third parties you need to compute triangles manually; there is no other way.

This is the C code I now use to generate rounded triangles:

void GenTri(char *retn, double xpos, double ypos, double scal, double angl) {
    double plus = M_PI * 2.0 / 3.0, dots[6] = {
        scal * cos(angl),              scal * sin(angl),
        scal * cos(angl + plus),       scal * sin(angl + plus),
        scal * cos(angl + plus * 2.0), scal * sin(angl + plus * 2.0)
    };
    sprintf(retn, "X%0.0fY%0.0fD02*\nX%0.0fY%0.0fD01*\n"
                  "X%0.0fY%0.0fD01*\nX%0.0fY%0.0fD01*\n",
            dots[0] + xpos, dots[1] + ypos, dots[2] + xpos, dots[3] + ypos,
            dots[4] + xpos, dots[5] + ypos, dots[0] + xpos, dots[1] + ypos);
}

...

GenTri(pstr, temp.x, -temp.y, data->scal * size, data->angl);
lptr += sprintf(bptr + lptr, "%sG36*\n%sG37*\n", pstr, pstr);

This is the corresponding Gerber output, unfortunately almost completely human-unreadable, unlike the «short» approach.

%FSLAX36Y36*%
%MOMM*%
G01*
%ADD10C,0.96000000*%
D10*
X72483601Y-39726784D02*
X57369097Y-32796289D01*
X58924363Y-49351081D01*
X72483601Y-39726784D01*
G36*
X72483601Y-39726784D02*
X57369097Y-32796289D01*
X58924363Y-49351081D01*
X72483601Y-39726784D01*
G37*