discuss@lists.openscad.org

OpenSCAD general discussion Mailing-list

View all threads

Math Behind the Code

GB
Glenn Butcher
Tue, Apr 14, 2026 7:10 PM

Disclaimer: I'm not a math person.

I'm building a CAD model of a vintage railroad baggage car, to help with
the visualization of design for a restoration project. In modeling the
framing internal to the walls, I need diagonal members between the
verticals; my first module to do that was 'carpenter style', where I
laid the diagonal between two vertical members and used difference() to
cut it.  This required an angle parameter that I had to 'scooch' around
to get the right angle.

What I wanted was a module that just took the height and spacing numbers
and made a parallelogram to fit and extruded it to the right thickness. 
So, I spent a few forays into the internets, searching for the math to
do that.  And, I just couldn't find it, even the AI search summaries
didn't complete the solution.  I finally gave in to the vibe coding
thing, and took the problem to Microsoft CoPilot, with which I had some
success building an OpenGL renderer.  To describe the problem I used
compass cardinal points to lay out the space, NE, NW, SE, SW to define
the four corners of the parallelogram.  Took 5 iterations to get it
close, and it still was plotting the NE corner on the wrong side of the
Y axis.  I finally just told it to negate that corner's vertical
component, ta-da, works.

Thing is, I do not understand the methodology.  I've inspected the
intermediate variables and I just don't have the math chops to
understand how the vectors yield the parallelogram sides.  Here's the code:

//algorithm courtesy Microsoft CoPilot:
module v2x4_diagonal(S, T) {
    //ggb: diagonal member dimensions
    w=4;  //ggb: height of the parallelogram
    t=2;

    // Upper edge endpoints
    NW = [0, T];
    SE = [S, 0];

    // Diagonal direction
    dx = S;
    dy = -T;
    L  = sqrt(dxdx + dydy);

    // Perpendicular unit vector (points downward)
    px = -T / L;
    py = -S / L;

    // Offset vector for lower edge
    ox = w * px;
    oy = w * py;

    // Lower edge parametric line: P(t) = NW + (ox, oy) + t*(dx, dy)

    // Intersection with x = 0 → SW
    t0 = -ox / dx;
    SW = [0,
          T + oy + t0 * dy];

    // Intersection with x = S → NE
    t1 = (S - ox) / dx;
    NE = [S,
          -(T + oy + t1 * dy)];  //ggb: I had to negate the Y coordinate

    // Correct winding order: NW → NE → SE → SW
    // ggb: extrude works in xy plane, rotate and translate to make it
'vertical',
    //        along the wall frame axis, Y.
    rotate([90,0,-90])
        translate([-S,0,-2])
            linear_extrude(height = t)
                polygon(points=[NW, NE, SE, SW]);
}

T=96;  //ggb: how tall is the framing
S=28;  //ggb: spacing between the framing members

translate([0,-2,0])cube([4,2,T]);
translate([0,S,0]) cube([4,2,T]);

color("green") v2x4_diagonal(S, T);

I offer this in the public domain, use as you see fit.  All I'd like to
get is some sort of explanation as to how it works...

Thanks,
Glenn Butcher

Disclaimer: I'm not a math person. I'm building a CAD model of a vintage railroad baggage car, to help with the visualization of design for a restoration project. In modeling the framing internal to the walls, I need diagonal members between the verticals; my first module to do that was 'carpenter style', where I laid the diagonal between two vertical members and used difference() to cut it.  This required an angle parameter that I had to 'scooch' around to get the right angle. What I wanted was a module that just took the height and spacing numbers and made a parallelogram to fit and extruded it to the right thickness.  So, I spent a few forays into the internets, searching for the math to do that.  And, I just couldn't find it, even the AI search summaries didn't complete the solution.  I finally gave in to the vibe coding thing, and took the problem to Microsoft CoPilot, with which I had some success building an OpenGL renderer.  To describe the problem I used compass cardinal points to lay out the space, NE, NW, SE, SW to define the four corners of the parallelogram.  Took 5 iterations to get it close, and it still was plotting the NE corner on the wrong side of the Y axis.  I finally just told it to negate that corner's vertical component, ta-da, works. Thing is, I do not understand the methodology.  I've inspected the intermediate variables and I just don't have the math chops to understand how the vectors yield the parallelogram sides.  Here's the code: //algorithm courtesy Microsoft CoPilot: module v2x4_diagonal(S, T) {     //ggb: diagonal member dimensions     w=4;  //ggb: height of the parallelogram     t=2;     // Upper edge endpoints     NW = [0, T];     SE = [S, 0];     // Diagonal direction     dx = S;     dy = -T;     L  = sqrt(dx*dx + dy*dy);     // Perpendicular unit vector (points downward)     px = -T / L;     py = -S / L;     // Offset vector for lower edge     ox = w * px;     oy = w * py;     // Lower edge parametric line: P(t) = NW + (ox, oy) + t*(dx, dy)     // Intersection with x = 0 → SW     t0 = -ox / dx;     SW = [0,           T + oy + t0 * dy];     // Intersection with x = S → NE     t1 = (S - ox) / dx;     NE = [S,           -(T + oy + t1 * dy)];  //ggb: I had to negate the Y coordinate     // Correct winding order: NW → NE → SE → SW     // ggb: extrude works in xy plane, rotate and translate to make it 'vertical',     //        along the wall frame axis, Y.     rotate([90,0,-90])         translate([-S,0,-2])             linear_extrude(height = t)                 polygon(points=[NW, NE, SE, SW]); } T=96;  //ggb: how tall is the framing S=28;  //ggb: spacing between the framing members translate([0,-2,0])cube([4,2,T]); translate([0,S,0]) cube([4,2,T]); color("green") v2x4_diagonal(S, T); I offer this in the public domain, use as you see fit.  All I'd like to get is some sort of explanation as to how it works... Thanks, Glenn Butcher
AD
Ari Diacou
Tue, Apr 14, 2026 8:58 PM

Hi Glenn,

This is a first. I have never seen AI written code before. Thank you for
introducing me to this absolute abomination. You cannot read it because it
is terrible. I haven't run the code, because I'm on my phone, and because
my curiosity of AI hallucinations does not overcome my mistrust of them.
But based on your description, this should be about 8 lines of vector
algebra (I estimate 4 lines of declaration, 4 lines of calculation, and one
line of something like linear_extrude () difference()...)

This is using vector calculus naming conventions for vector algebra. Like,
I can see how it could be right, but I can also see how no programmer would
ever write this garbage*. It took me about a minute to absolutely fear for
civilization if we are firing human programmers in favor of algorithms that
write this garbage*.

*By garbage I of course mean at least 10 explative adjectives followed by
the vilest noun in the readers native language.

Cheers,
A slightly more Luddite ex-physicist.

On Tue, Apr 14, 2026, 3:10 PM Glenn Butcher via Discuss <
discuss@lists.openscad.org> wrote:

Disclaimer: I'm not a math person.

I'm building a CAD model of a vintage railroad baggage car, to help with
the visualization of design for a restoration project. In modeling the
framing internal to the walls, I need diagonal members between the
verticals; my first module to do that was 'carpenter style', where I
laid the diagonal between two vertical members and used difference() to
cut it.  This required an angle parameter that I had to 'scooch' around
to get the right angle.

What I wanted was a module that just took the height and spacing numbers
and made a parallelogram to fit and extruded it to the right thickness.
So, I spent a few forays into the internets, searching for the math to
do that.  And, I just couldn't find it, even the AI search summaries
didn't complete the solution.  I finally gave in to the vibe coding
thing, and took the problem to Microsoft CoPilot, with which I had some
success building an OpenGL renderer.  To describe the problem I used
compass cardinal points to lay out the space, NE, NW, SE, SW to define
the four corners of the parallelogram.  Took 5 iterations to get it
close, and it still was plotting the NE corner on the wrong side of the
Y axis.  I finally just told it to negate that corner's vertical
component, ta-da, works.

Thing is, I do not understand the methodology.  I've inspected the
intermediate variables and I just don't have the math chops to
understand how the vectors yield the parallelogram sides.  Here's the code:

//algorithm courtesy Microsoft CoPilot:
module v2x4_diagonal(S, T) {
//ggb: diagonal member dimensions
w=4;  //ggb: height of the parallelogram
t=2;

  // Upper edge endpoints
  NW = [0, T];
  SE = [S, 0];

  // Diagonal direction
  dx = S;
  dy = -T;
  L  = sqrt(dx*dx + dy*dy);

  // Perpendicular unit vector (points downward)
  px = -T / L;
  py = -S / L;

  // Offset vector for lower edge
  ox = w * px;
  oy = w * py;

  // Lower edge parametric line: P(t) = NW + (ox, oy) + t*(dx, dy)

  // Intersection with x = 0 → SW
  t0 = -ox / dx;
  SW = [0,
        T + oy + t0 * dy];

  // Intersection with x = S → NE
  t1 = (S - ox) / dx;
  NE = [S,
        -(T + oy + t1 * dy)];  //ggb: I had to negate the Y coordinate

  // Correct winding order: NW → NE → SE → SW
  // ggb: extrude works in xy plane, rotate and translate to make it

'vertical',
//        along the wall frame axis, Y.
rotate([90,0,-90])
translate([-S,0,-2])
linear_extrude(height = t)
polygon(points=[NW, NE, SE, SW]);
}

T=96;  //ggb: how tall is the framing
S=28;  //ggb: spacing between the framing members

translate([0,-2,0])cube([4,2,T]);
translate([0,S,0]) cube([4,2,T]);

color("green") v2x4_diagonal(S, T);

I offer this in the public domain, use as you see fit.  All I'd like to
get is some sort of explanation as to how it works...

Thanks,
Glenn Butcher


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

Hi Glenn, This is a first. I have never seen AI written code before. Thank you for introducing me to this absolute abomination. You cannot read it because it is terrible. I haven't run the code, because I'm on my phone, and because my curiosity of AI hallucinations does not overcome my mistrust of them. But based on your description, this should be about 8 lines of vector algebra (I estimate 4 lines of declaration, 4 lines of calculation, and one line of something like linear_extrude () difference()...) This is using vector calculus naming conventions for vector algebra. Like, I can see how it could be right, but I can also see how no programmer would ever write this garbage*. It took me about a minute to absolutely fear for civilization if we are firing human programmers in favor of algorithms that write this garbage*. *By garbage I of course mean at least 10 explative adjectives followed by the vilest noun in the readers native language. Cheers, A slightly more Luddite ex-physicist. On Tue, Apr 14, 2026, 3:10 PM Glenn Butcher via Discuss < discuss@lists.openscad.org> wrote: > Disclaimer: I'm not a math person. > > I'm building a CAD model of a vintage railroad baggage car, to help with > the visualization of design for a restoration project. In modeling the > framing internal to the walls, I need diagonal members between the > verticals; my first module to do that was 'carpenter style', where I > laid the diagonal between two vertical members and used difference() to > cut it. This required an angle parameter that I had to 'scooch' around > to get the right angle. > > What I wanted was a module that just took the height and spacing numbers > and made a parallelogram to fit and extruded it to the right thickness. > So, I spent a few forays into the internets, searching for the math to > do that. And, I just couldn't find it, even the AI search summaries > didn't complete the solution. I finally gave in to the vibe coding > thing, and took the problem to Microsoft CoPilot, with which I had some > success building an OpenGL renderer. To describe the problem I used > compass cardinal points to lay out the space, NE, NW, SE, SW to define > the four corners of the parallelogram. Took 5 iterations to get it > close, and it still was plotting the NE corner on the wrong side of the > Y axis. I finally just told it to negate that corner's vertical > component, ta-da, works. > > Thing is, I do not understand the methodology. I've inspected the > intermediate variables and I just don't have the math chops to > understand how the vectors yield the parallelogram sides. Here's the code: > > //algorithm courtesy Microsoft CoPilot: > module v2x4_diagonal(S, T) { > //ggb: diagonal member dimensions > w=4; //ggb: height of the parallelogram > t=2; > > // Upper edge endpoints > NW = [0, T]; > SE = [S, 0]; > > // Diagonal direction > dx = S; > dy = -T; > L = sqrt(dx*dx + dy*dy); > > // Perpendicular unit vector (points downward) > px = -T / L; > py = -S / L; > > // Offset vector for lower edge > ox = w * px; > oy = w * py; > > // Lower edge parametric line: P(t) = NW + (ox, oy) + t*(dx, dy) > > // Intersection with x = 0 → SW > t0 = -ox / dx; > SW = [0, > T + oy + t0 * dy]; > > // Intersection with x = S → NE > t1 = (S - ox) / dx; > NE = [S, > -(T + oy + t1 * dy)]; //ggb: I had to negate the Y coordinate > > // Correct winding order: NW → NE → SE → SW > // ggb: extrude works in xy plane, rotate and translate to make it > 'vertical', > // along the wall frame axis, Y. > rotate([90,0,-90]) > translate([-S,0,-2]) > linear_extrude(height = t) > polygon(points=[NW, NE, SE, SW]); > } > > T=96; //ggb: how tall is the framing > S=28; //ggb: spacing between the framing members > > translate([0,-2,0])cube([4,2,T]); > translate([0,S,0]) cube([4,2,T]); > > color("green") v2x4_diagonal(S, T); > > I offer this in the public domain, use as you see fit. All I'd like to > get is some sort of explanation as to how it works... > > Thanks, > Glenn Butcher > > > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org
LM
Leonard Martin Struttmann
Tue, Apr 14, 2026 9:10 PM

And, on top of that, it doesn't seem to be correct.  When I ran that code,
the diagonal brace turned out to be 2x4.63 instead of the specified 2x4.

On Tue, Apr 14, 2026 at 3:59 PM Ari Diacou via Discuss <
discuss@lists.openscad.org> wrote:

Hi Glenn,

This is a first. I have never seen AI written code before. Thank you for
introducing me to this absolute abomination. You cannot read it because it
is terrible. I haven't run the code, because I'm on my phone, and because
my curiosity of AI hallucinations does not overcome my mistrust of them.
But based on your description, this should be about 8 lines of vector
algebra (I estimate 4 lines of declaration, 4 lines of calculation, and one
line of something like linear_extrude () difference()...)

This is using vector calculus naming conventions for vector algebra. Like,
I can see how it could be right, but I can also see how no programmer would
ever write this garbage*. It took me about a minute to absolutely fear for
civilization if we are firing human programmers in favor of algorithms that
write this garbage*.

*By garbage I of course mean at least 10 explative adjectives followed by
the vilest noun in the readers native language.

Cheers,
A slightly more Luddite ex-physicist.

On Tue, Apr 14, 2026, 3:10 PM Glenn Butcher via Discuss <
discuss@lists.openscad.org> wrote:

Disclaimer: I'm not a math person.

I'm building a CAD model of a vintage railroad baggage car, to help with
the visualization of design for a restoration project. In modeling the
framing internal to the walls, I need diagonal members between the
verticals; my first module to do that was 'carpenter style', where I
laid the diagonal between two vertical members and used difference() to
cut it.  This required an angle parameter that I had to 'scooch' around
to get the right angle.

What I wanted was a module that just took the height and spacing numbers
and made a parallelogram to fit and extruded it to the right thickness.
So, I spent a few forays into the internets, searching for the math to
do that.  And, I just couldn't find it, even the AI search summaries
didn't complete the solution.  I finally gave in to the vibe coding
thing, and took the problem to Microsoft CoPilot, with which I had some
success building an OpenGL renderer.  To describe the problem I used
compass cardinal points to lay out the space, NE, NW, SE, SW to define
the four corners of the parallelogram.  Took 5 iterations to get it
close, and it still was plotting the NE corner on the wrong side of the
Y axis.  I finally just told it to negate that corner's vertical
component, ta-da, works.

Thing is, I do not understand the methodology.  I've inspected the
intermediate variables and I just don't have the math chops to
understand how the vectors yield the parallelogram sides.  Here's the
code:

//algorithm courtesy Microsoft CoPilot:
module v2x4_diagonal(S, T) {
//ggb: diagonal member dimensions
w=4;  //ggb: height of the parallelogram
t=2;

  // Upper edge endpoints
  NW = [0, T];
  SE = [S, 0];

  // Diagonal direction
  dx = S;
  dy = -T;
  L  = sqrt(dx*dx + dy*dy);

  // Perpendicular unit vector (points downward)
  px = -T / L;
  py = -S / L;

  // Offset vector for lower edge
  ox = w * px;
  oy = w * py;

  // Lower edge parametric line: P(t) = NW + (ox, oy) + t*(dx, dy)

  // Intersection with x = 0 → SW
  t0 = -ox / dx;
  SW = [0,
        T + oy + t0 * dy];

  // Intersection with x = S → NE
  t1 = (S - ox) / dx;
  NE = [S,
        -(T + oy + t1 * dy)];  //ggb: I had to negate the Y coordinate

  // Correct winding order: NW → NE → SE → SW
  // ggb: extrude works in xy plane, rotate and translate to make it

'vertical',
//        along the wall frame axis, Y.
rotate([90,0,-90])
translate([-S,0,-2])
linear_extrude(height = t)
polygon(points=[NW, NE, SE, SW]);
}

T=96;  //ggb: how tall is the framing
S=28;  //ggb: spacing between the framing members

translate([0,-2,0])cube([4,2,T]);
translate([0,S,0]) cube([4,2,T]);

color("green") v2x4_diagonal(S, T);

I offer this in the public domain, use as you see fit.  All I'd like to
get is some sort of explanation as to how it works...

Thanks,
Glenn Butcher


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

And, on top of that, it doesn't seem to be correct. When I ran that code, the diagonal brace turned out to be 2x4.63 instead of the specified 2x4. On Tue, Apr 14, 2026 at 3:59 PM Ari Diacou via Discuss < discuss@lists.openscad.org> wrote: > Hi Glenn, > > This is a first. I have never seen AI written code before. Thank you for > introducing me to this absolute abomination. You cannot read it because it > is terrible. I haven't run the code, because I'm on my phone, and because > my curiosity of AI hallucinations does not overcome my mistrust of them. > But based on your description, this should be about 8 lines of vector > algebra (I estimate 4 lines of declaration, 4 lines of calculation, and one > line of something like linear_extrude () difference()...) > > This is using vector calculus naming conventions for vector algebra. Like, > I can see how it could be right, but I can also see how no programmer would > ever write this garbage*. It took me about a minute to absolutely fear for > civilization if we are firing human programmers in favor of algorithms that > write this garbage*. > > *By garbage I of course mean at least 10 explative adjectives followed by > the vilest noun in the readers native language. > > Cheers, > A slightly more Luddite ex-physicist. > > On Tue, Apr 14, 2026, 3:10 PM Glenn Butcher via Discuss < > discuss@lists.openscad.org> wrote: > >> Disclaimer: I'm not a math person. >> >> I'm building a CAD model of a vintage railroad baggage car, to help with >> the visualization of design for a restoration project. In modeling the >> framing internal to the walls, I need diagonal members between the >> verticals; my first module to do that was 'carpenter style', where I >> laid the diagonal between two vertical members and used difference() to >> cut it. This required an angle parameter that I had to 'scooch' around >> to get the right angle. >> >> What I wanted was a module that just took the height and spacing numbers >> and made a parallelogram to fit and extruded it to the right thickness. >> So, I spent a few forays into the internets, searching for the math to >> do that. And, I just couldn't find it, even the AI search summaries >> didn't complete the solution. I finally gave in to the vibe coding >> thing, and took the problem to Microsoft CoPilot, with which I had some >> success building an OpenGL renderer. To describe the problem I used >> compass cardinal points to lay out the space, NE, NW, SE, SW to define >> the four corners of the parallelogram. Took 5 iterations to get it >> close, and it still was plotting the NE corner on the wrong side of the >> Y axis. I finally just told it to negate that corner's vertical >> component, ta-da, works. >> >> Thing is, I do not understand the methodology. I've inspected the >> intermediate variables and I just don't have the math chops to >> understand how the vectors yield the parallelogram sides. Here's the >> code: >> >> //algorithm courtesy Microsoft CoPilot: >> module v2x4_diagonal(S, T) { >> //ggb: diagonal member dimensions >> w=4; //ggb: height of the parallelogram >> t=2; >> >> // Upper edge endpoints >> NW = [0, T]; >> SE = [S, 0]; >> >> // Diagonal direction >> dx = S; >> dy = -T; >> L = sqrt(dx*dx + dy*dy); >> >> // Perpendicular unit vector (points downward) >> px = -T / L; >> py = -S / L; >> >> // Offset vector for lower edge >> ox = w * px; >> oy = w * py; >> >> // Lower edge parametric line: P(t) = NW + (ox, oy) + t*(dx, dy) >> >> // Intersection with x = 0 → SW >> t0 = -ox / dx; >> SW = [0, >> T + oy + t0 * dy]; >> >> // Intersection with x = S → NE >> t1 = (S - ox) / dx; >> NE = [S, >> -(T + oy + t1 * dy)]; //ggb: I had to negate the Y coordinate >> >> // Correct winding order: NW → NE → SE → SW >> // ggb: extrude works in xy plane, rotate and translate to make it >> 'vertical', >> // along the wall frame axis, Y. >> rotate([90,0,-90]) >> translate([-S,0,-2]) >> linear_extrude(height = t) >> polygon(points=[NW, NE, SE, SW]); >> } >> >> T=96; //ggb: how tall is the framing >> S=28; //ggb: spacing between the framing members >> >> translate([0,-2,0])cube([4,2,T]); >> translate([0,S,0]) cube([4,2,T]); >> >> color("green") v2x4_diagonal(S, T); >> >> I offer this in the public domain, use as you see fit. All I'd like to >> get is some sort of explanation as to how it works... >> >> Thanks, >> Glenn Butcher >> >> >> >> _______________________________________________ >> OpenSCAD mailing list >> To unsubscribe send an email to discuss-leave@lists.openscad.org > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org
GB
Glenn Butcher
Tue, Apr 14, 2026 9:37 PM

Leonard,

Ooh, that's helpful.  I've been eyeballing it, didn't notice that
difference in width.

I've been OpenSCAD-ing various building components, roofs (rise:run),
brick arches (span:height), even polygon curves (min-circle), and I've
readily found the requisite math to do such, but this parallelogram has
just stumped me.  Not a fan of this 'vibe coding' thing, but I've tried
'gimme-example' tasks and I've learned about things like OpenGL
rendering that way.  I get your disdain, too easy for folk to just wing
it, so I'm trying not to blindly rely on it for this problem.

Talking about the math, there seems to not be enough information in the
parameters to which I've constrained the problem, for the parallelogram
that would be its height (the 4" board dimension), and the diagonal
length (sqrt(SS + TT)).  Or, am I just too ill-informed to see it.

Regards,
Glenn
Skeptical ex-software person

On 4/14/2026 3:10 PM, Leonard Martin Struttmann via Discuss wrote:

And, on top of that, it doesn't seem to be correct.  When I ran that
code, the diagonal brace turned out to be 2x4.63 instead of the
specified 2x4.

On Tue, Apr 14, 2026 at 3:59 PM Ari Diacou via Discuss
discuss@lists.openscad.org wrote:

 Hi Glenn,

 This is a first. I have never seen AI written code before. Thank
 you for introducing me to this absolute abomination. You cannot
 read it because it is terrible. I haven't run the code, because
 I'm on my phone, and because my curiosity of AI hallucinations
 does not overcome my mistrust of them. But based on your
 description, this should be about 8 lines of vector algebra (I
 estimate 4 lines of declaration, 4 lines of calculation, and one
 line of something like linear_extrude () difference()...)

 This is using vector calculus naming conventions for vector
 algebra. Like, I can see how it could be right, but I can also see
 how no programmer would ever write this garbage*. It took me about
 a minute to absolutely fear for civilization if we are firing
 human programmers in favor of algorithms that write this garbage*.

 *By garbage I of course mean at least 10 explative adjectives
 followed by the vilest noun in the readers native language.

 Cheers,
 A slightly more Luddite ex-physicist.

 On Tue, Apr 14, 2026, 3:10 PM Glenn Butcher via Discuss
 <discuss@lists.openscad.org> wrote:

     Disclaimer: I'm not a math person.

     I'm building a CAD model of a vintage railroad baggage car, to
     help with
     the visualization of design for a restoration project. In
     modeling the
     framing internal to the walls, I need diagonal members between
     the
     verticals; my first module to do that was 'carpenter style',
     where I
     laid the diagonal between two vertical members and used
     difference() to
     cut it.  This required an angle parameter that I had to
     'scooch' around
     to get the right angle.

     What I wanted was a module that just took the height and
     spacing numbers
     and made a parallelogram to fit and extruded it to the right
     thickness.
     So, I spent a few forays into the internets, searching for the
     math to
     do that.  And, I just couldn't find it, even the AI search
     summaries
     didn't complete the solution.  I finally gave in to the vibe
     coding
     thing, and took the problem to Microsoft CoPilot, with which I
     had some
     success building an OpenGL renderer.  To describe the problem
     I used
     compass cardinal points to lay out the space, NE, NW, SE, SW
     to define
     the four corners of the parallelogram.  Took 5 iterations to
     get it
     close, and it still was plotting the NE corner on the wrong
     side of the
     Y axis.  I finally just told it to negate that corner's vertical
     component, ta-da, works.

     Thing is, I do not understand the methodology.  I've inspected
     the
     intermediate variables and I just don't have the math chops to
     understand how the vectors yield the parallelogram sides. 
     Here's the code:

     //algorithm courtesy Microsoft CoPilot:
     module v2x4_diagonal(S, T) {
          //ggb: diagonal member dimensions
          w=4;  //ggb: height of the parallelogram
          t=2;

          // Upper edge endpoints
          NW = [0, T];
          SE = [S, 0];

          // Diagonal direction
          dx = S;
          dy = -T;
          L  = sqrt(dx*dx + dy*dy);

          // Perpendicular unit vector (points downward)
          px = -T / L;
          py = -S / L;

          // Offset vector for lower edge
          ox = w * px;
          oy = w * py;

          // Lower edge parametric line: P(t) = NW + (ox, oy) +
     t*(dx, dy)

          // Intersection with x = 0 → SW
          t0 = -ox / dx;
          SW = [0,
                T + oy + t0 * dy];

          // Intersection with x = S → NE
          t1 = (S - ox) / dx;
          NE = [S,
                -(T + oy + t1 * dy)];  //ggb: I had to negate the Y
     coordinate

          // Correct winding order: NW → NE → SE → SW
          // ggb: extrude works in xy plane, rotate and translate
     to make it
     'vertical',
          //        along the wall frame axis, Y.
          rotate([90,0,-90])
              translate([-S,0,-2])
                  linear_extrude(height = t)
                      polygon(points=[NW, NE, SE, SW]);
     }

     T=96;  //ggb: how tall is the framing
     S=28;  //ggb: spacing between the framing members

     translate([0,-2,0])cube([4,2,T]);
     translate([0,S,0]) cube([4,2,T]);

     color("green") v2x4_diagonal(S, T);

     I offer this in the public domain, use as you see fit.  All
     I'd like to
     get is some sort of explanation as to how it works...

     Thanks,
     Glenn Butcher



     _______________________________________________
     OpenSCAD mailing list
     To unsubscribe send an email to discuss-leave@lists.openscad.org

 _______________________________________________
 OpenSCAD mailing list
 To unsubscribe send an email to discuss-leave@lists.openscad.org

OpenSCAD mailing list
To unsubscribe send an email todiscuss-leave@lists.openscad.org

Leonard, Ooh, that's helpful.  I've been eyeballing it, didn't notice that difference in width. I've been OpenSCAD-ing various building components, roofs (rise:run), brick arches (span:height), even polygon curves (min-circle), and I've readily found the requisite math to do such, but this parallelogram has just stumped me.  Not a fan of this 'vibe coding' thing, but I've tried 'gimme-example' tasks and I've learned about things like OpenGL rendering that way.  I get your disdain, too easy for folk to just wing it, so I'm trying not to blindly rely on it for this problem. Talking about the math, there seems to not be enough information in the parameters to which I've constrained the problem, for the parallelogram that would be its height (the 4" board dimension), and the diagonal length (sqrt(S*S + T*T)).  Or, am I just too ill-informed to see it. Regards, Glenn Skeptical ex-software person On 4/14/2026 3:10 PM, Leonard Martin Struttmann via Discuss wrote: > And, on top of that, it doesn't seem to be correct.  When I ran that > code, the diagonal brace turned out to be 2x4.63 instead of the > specified 2x4. > > On Tue, Apr 14, 2026 at 3:59 PM Ari Diacou via Discuss > <discuss@lists.openscad.org> wrote: > > Hi Glenn, > > This is a first. I have never seen AI written code before. Thank > you for introducing me to this absolute abomination. You cannot > read it because it is terrible. I haven't run the code, because > I'm on my phone, and because my curiosity of AI hallucinations > does not overcome my mistrust of them. But based on your > description, this should be about 8 lines of vector algebra (I > estimate 4 lines of declaration, 4 lines of calculation, and one > line of something like linear_extrude () difference()...) > > This is using vector calculus naming conventions for vector > algebra. Like, I can see how it could be right, but I can also see > how no programmer would ever write this garbage*. It took me about > a minute to absolutely fear for civilization if we are firing > human programmers in favor of algorithms that write this garbage*. > > *By garbage I of course mean at least 10 explative adjectives > followed by the vilest noun in the readers native language. > > Cheers, > A slightly more Luddite ex-physicist. > > On Tue, Apr 14, 2026, 3:10 PM Glenn Butcher via Discuss > <discuss@lists.openscad.org> wrote: > > Disclaimer: I'm not a math person. > > I'm building a CAD model of a vintage railroad baggage car, to > help with > the visualization of design for a restoration project. In > modeling the > framing internal to the walls, I need diagonal members between > the > verticals; my first module to do that was 'carpenter style', > where I > laid the diagonal between two vertical members and used > difference() to > cut it.  This required an angle parameter that I had to > 'scooch' around > to get the right angle. > > What I wanted was a module that just took the height and > spacing numbers > and made a parallelogram to fit and extruded it to the right > thickness. > So, I spent a few forays into the internets, searching for the > math to > do that.  And, I just couldn't find it, even the AI search > summaries > didn't complete the solution.  I finally gave in to the vibe > coding > thing, and took the problem to Microsoft CoPilot, with which I > had some > success building an OpenGL renderer.  To describe the problem > I used > compass cardinal points to lay out the space, NE, NW, SE, SW > to define > the four corners of the parallelogram.  Took 5 iterations to > get it > close, and it still was plotting the NE corner on the wrong > side of the > Y axis.  I finally just told it to negate that corner's vertical > component, ta-da, works. > > Thing is, I do not understand the methodology.  I've inspected > the > intermediate variables and I just don't have the math chops to > understand how the vectors yield the parallelogram sides.  > Here's the code: > > //algorithm courtesy Microsoft CoPilot: > module v2x4_diagonal(S, T) { >      //ggb: diagonal member dimensions >      w=4;  //ggb: height of the parallelogram >      t=2; > >      // Upper edge endpoints >      NW = [0, T]; >      SE = [S, 0]; > >      // Diagonal direction >      dx = S; >      dy = -T; >      L  = sqrt(dx*dx + dy*dy); > >      // Perpendicular unit vector (points downward) >      px = -T / L; >      py = -S / L; > >      // Offset vector for lower edge >      ox = w * px; >      oy = w * py; > >      // Lower edge parametric line: P(t) = NW + (ox, oy) + > t*(dx, dy) > >      // Intersection with x = 0 → SW >      t0 = -ox / dx; >      SW = [0, >            T + oy + t0 * dy]; > >      // Intersection with x = S → NE >      t1 = (S - ox) / dx; >      NE = [S, >            -(T + oy + t1 * dy)];  //ggb: I had to negate the Y > coordinate > >      // Correct winding order: NW → NE → SE → SW >      // ggb: extrude works in xy plane, rotate and translate > to make it > 'vertical', >      //        along the wall frame axis, Y. >      rotate([90,0,-90]) >          translate([-S,0,-2]) >              linear_extrude(height = t) >                  polygon(points=[NW, NE, SE, SW]); > } > > T=96;  //ggb: how tall is the framing > S=28;  //ggb: spacing between the framing members > > translate([0,-2,0])cube([4,2,T]); > translate([0,S,0]) cube([4,2,T]); > > color("green") v2x4_diagonal(S, T); > > I offer this in the public domain, use as you see fit.  All > I'd like to > get is some sort of explanation as to how it works... > > Thanks, > Glenn Butcher > > > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org > > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email todiscuss-leave@lists.openscad.org
LM
Leonard Martin Struttmann
Tue, Apr 14, 2026 11:26 PM

Here's what Claude came up with:

module test( S, L, W )
{
inner = sqrt(S * S + L * L - W * W);
factor = (S * inner - L * W) / (S * S - W * W);

face_length  = S * factor;  // d: long diagonal sides
stud_contact = W * factor;  // h: short vertical sides

points = [ [ 0,0 ],
[ 0, stud_contact ],
[ S, L ],
[ S, L-stud_contact ]] ;

rotate( [ 90, 0, 0 ])
rotate( [ 0, 90, 0 ])
linear_extrude(height = 2, center = false, convexity = 10, twist = 0,
slices = 20, scale = 1.0)
polygon(points = points);
}
T=96;  //ggb: how tall is the framing
S=28;  //ggb: spacing between the framing members

translate([0,-2,0])cube([4,2,T]);
translate([0,S,0]) cube([4,2,T]);

#v2x4_diagonal(S, T);

test( S, T, 4 );

On Tue, Apr 14, 2026 at 4:37 PM Glenn Butcher via Discuss <
discuss@lists.openscad.org> wrote:

Leonard,

Ooh, that's helpful.  I've been eyeballing it, didn't notice that
difference in width.

I've been OpenSCAD-ing various building components, roofs (rise:run),
brick arches (span:height), even polygon curves (min-circle), and I've
readily found the requisite math to do such, but this parallelogram has
just stumped me.  Not a fan of this 'vibe coding' thing, but I've tried
'gimme-example' tasks and I've learned about things like OpenGL rendering
that way.  I get your disdain, too easy for folk to just wing it, so I'm
trying not to blindly rely on it for this problem.

Talking about the math, there seems to not be enough information in the
parameters to which I've constrained the problem, for the parallelogram
that would be its height (the 4" board dimension), and the diagonal length
(sqrt(SS + TT)).  Or, am I just too ill-informed to see it.

Regards,
Glenn
Skeptical ex-software person
On 4/14/2026 3:10 PM, Leonard Martin Struttmann via Discuss wrote:

And, on top of that, it doesn't seem to be correct.  When I ran that code,
the diagonal brace turned out to be 2x4.63 instead of the specified 2x4.

On Tue, Apr 14, 2026 at 3:59 PM Ari Diacou via Discuss <
discuss@lists.openscad.org> wrote:

Hi Glenn,

This is a first. I have never seen AI written code before. Thank you for
introducing me to this absolute abomination. You cannot read it because it
is terrible. I haven't run the code, because I'm on my phone, and because
my curiosity of AI hallucinations does not overcome my mistrust of them.
But based on your description, this should be about 8 lines of vector
algebra (I estimate 4 lines of declaration, 4 lines of calculation, and one
line of something like linear_extrude () difference()...)

This is using vector calculus naming conventions for vector algebra.
Like, I can see how it could be right, but I can also see how no programmer
would ever write this garbage*. It took me about a minute to absolutely
fear for civilization if we are firing human programmers in favor of
algorithms that write this garbage*.

*By garbage I of course mean at least 10 explative adjectives followed by
the vilest noun in the readers native language.

Cheers,
A slightly more Luddite ex-physicist.

On Tue, Apr 14, 2026, 3:10 PM Glenn Butcher via Discuss <
discuss@lists.openscad.org> wrote:

Disclaimer: I'm not a math person.

I'm building a CAD model of a vintage railroad baggage car, to help with
the visualization of design for a restoration project. In modeling the
framing internal to the walls, I need diagonal members between the
verticals; my first module to do that was 'carpenter style', where I
laid the diagonal between two vertical members and used difference() to
cut it.  This required an angle parameter that I had to 'scooch' around
to get the right angle.

What I wanted was a module that just took the height and spacing numbers
and made a parallelogram to fit and extruded it to the right thickness.
So, I spent a few forays into the internets, searching for the math to
do that.  And, I just couldn't find it, even the AI search summaries
didn't complete the solution.  I finally gave in to the vibe coding
thing, and took the problem to Microsoft CoPilot, with which I had some
success building an OpenGL renderer.  To describe the problem I used
compass cardinal points to lay out the space, NE, NW, SE, SW to define
the four corners of the parallelogram.  Took 5 iterations to get it
close, and it still was plotting the NE corner on the wrong side of the
Y axis.  I finally just told it to negate that corner's vertical
component, ta-da, works.

Thing is, I do not understand the methodology.  I've inspected the
intermediate variables and I just don't have the math chops to
understand how the vectors yield the parallelogram sides.  Here's the
code:

//algorithm courtesy Microsoft CoPilot:
module v2x4_diagonal(S, T) {
//ggb: diagonal member dimensions
w=4;  //ggb: height of the parallelogram
t=2;

  // Upper edge endpoints
  NW = [0, T];
  SE = [S, 0];

  // Diagonal direction
  dx = S;
  dy = -T;
  L  = sqrt(dx*dx + dy*dy);

  // Perpendicular unit vector (points downward)
  px = -T / L;
  py = -S / L;

  // Offset vector for lower edge
  ox = w * px;
  oy = w * py;

  // Lower edge parametric line: P(t) = NW + (ox, oy) + t*(dx, dy)

  // Intersection with x = 0 → SW
  t0 = -ox / dx;
  SW = [0,
        T + oy + t0 * dy];

  // Intersection with x = S → NE
  t1 = (S - ox) / dx;
  NE = [S,
        -(T + oy + t1 * dy)];  //ggb: I had to negate the Y coordinate

  // Correct winding order: NW → NE → SE → SW
  // ggb: extrude works in xy plane, rotate and translate to make it

'vertical',
//        along the wall frame axis, Y.
rotate([90,0,-90])
translate([-S,0,-2])
linear_extrude(height = t)
polygon(points=[NW, NE, SE, SW]);
}

T=96;  //ggb: how tall is the framing
S=28;  //ggb: spacing between the framing members

translate([0,-2,0])cube([4,2,T]);
translate([0,S,0]) cube([4,2,T]);

color("green") v2x4_diagonal(S, T);

I offer this in the public domain, use as you see fit.  All I'd like to
get is some sort of explanation as to how it works...

Thanks,
Glenn Butcher


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

Here's what Claude came up with: module test( S, L, W ) { inner = sqrt(S * S + L * L - W * W); factor = (S * inner - L * W) / (S * S - W * W); face_length = S * factor; // d: long diagonal sides stud_contact = W * factor; // h: short vertical sides points = [ [ 0,0 ], [ 0, stud_contact ], [ S, L ], [ S, L-stud_contact ]] ; rotate( [ 90, 0, 0 ]) rotate( [ 0, 90, 0 ]) linear_extrude(height = 2, center = false, convexity = 10, twist = 0, slices = 20, scale = 1.0) polygon(points = points); } T=96; //ggb: how tall is the framing S=28; //ggb: spacing between the framing members translate([0,-2,0])cube([4,2,T]); translate([0,S,0]) cube([4,2,T]); #v2x4_diagonal(S, T); test( S, T, 4 ); On Tue, Apr 14, 2026 at 4:37 PM Glenn Butcher via Discuss < discuss@lists.openscad.org> wrote: > Leonard, > > Ooh, that's helpful. I've been eyeballing it, didn't notice that > difference in width. > > I've been OpenSCAD-ing various building components, roofs (rise:run), > brick arches (span:height), even polygon curves (min-circle), and I've > readily found the requisite math to do such, but this parallelogram has > just stumped me. Not a fan of this 'vibe coding' thing, but I've tried > 'gimme-example' tasks and I've learned about things like OpenGL rendering > that way. I get your disdain, too easy for folk to just wing it, so I'm > trying not to blindly rely on it for this problem. > > Talking about the math, there seems to not be enough information in the > parameters to which I've constrained the problem, for the parallelogram > that would be its height (the 4" board dimension), and the diagonal length > (sqrt(S*S + T*T)). Or, am I just too ill-informed to see it. > > Regards, > Glenn > Skeptical ex-software person > On 4/14/2026 3:10 PM, Leonard Martin Struttmann via Discuss wrote: > > And, on top of that, it doesn't seem to be correct. When I ran that code, > the diagonal brace turned out to be 2x4.63 instead of the specified 2x4. > > On Tue, Apr 14, 2026 at 3:59 PM Ari Diacou via Discuss < > discuss@lists.openscad.org> wrote: > >> Hi Glenn, >> >> This is a first. I have never seen AI written code before. Thank you for >> introducing me to this absolute abomination. You cannot read it because it >> is terrible. I haven't run the code, because I'm on my phone, and because >> my curiosity of AI hallucinations does not overcome my mistrust of them. >> But based on your description, this should be about 8 lines of vector >> algebra (I estimate 4 lines of declaration, 4 lines of calculation, and one >> line of something like linear_extrude () difference()...) >> >> This is using vector calculus naming conventions for vector algebra. >> Like, I can see how it could be right, but I can also see how no programmer >> would ever write this garbage*. It took me about a minute to absolutely >> fear for civilization if we are firing human programmers in favor of >> algorithms that write this garbage*. >> >> *By garbage I of course mean at least 10 explative adjectives followed by >> the vilest noun in the readers native language. >> >> Cheers, >> A slightly more Luddite ex-physicist. >> >> On Tue, Apr 14, 2026, 3:10 PM Glenn Butcher via Discuss < >> discuss@lists.openscad.org> wrote: >> >>> Disclaimer: I'm not a math person. >>> >>> I'm building a CAD model of a vintage railroad baggage car, to help with >>> the visualization of design for a restoration project. In modeling the >>> framing internal to the walls, I need diagonal members between the >>> verticals; my first module to do that was 'carpenter style', where I >>> laid the diagonal between two vertical members and used difference() to >>> cut it. This required an angle parameter that I had to 'scooch' around >>> to get the right angle. >>> >>> What I wanted was a module that just took the height and spacing numbers >>> and made a parallelogram to fit and extruded it to the right thickness. >>> So, I spent a few forays into the internets, searching for the math to >>> do that. And, I just couldn't find it, even the AI search summaries >>> didn't complete the solution. I finally gave in to the vibe coding >>> thing, and took the problem to Microsoft CoPilot, with which I had some >>> success building an OpenGL renderer. To describe the problem I used >>> compass cardinal points to lay out the space, NE, NW, SE, SW to define >>> the four corners of the parallelogram. Took 5 iterations to get it >>> close, and it still was plotting the NE corner on the wrong side of the >>> Y axis. I finally just told it to negate that corner's vertical >>> component, ta-da, works. >>> >>> Thing is, I do not understand the methodology. I've inspected the >>> intermediate variables and I just don't have the math chops to >>> understand how the vectors yield the parallelogram sides. Here's the >>> code: >>> >>> //algorithm courtesy Microsoft CoPilot: >>> module v2x4_diagonal(S, T) { >>> //ggb: diagonal member dimensions >>> w=4; //ggb: height of the parallelogram >>> t=2; >>> >>> // Upper edge endpoints >>> NW = [0, T]; >>> SE = [S, 0]; >>> >>> // Diagonal direction >>> dx = S; >>> dy = -T; >>> L = sqrt(dx*dx + dy*dy); >>> >>> // Perpendicular unit vector (points downward) >>> px = -T / L; >>> py = -S / L; >>> >>> // Offset vector for lower edge >>> ox = w * px; >>> oy = w * py; >>> >>> // Lower edge parametric line: P(t) = NW + (ox, oy) + t*(dx, dy) >>> >>> // Intersection with x = 0 → SW >>> t0 = -ox / dx; >>> SW = [0, >>> T + oy + t0 * dy]; >>> >>> // Intersection with x = S → NE >>> t1 = (S - ox) / dx; >>> NE = [S, >>> -(T + oy + t1 * dy)]; //ggb: I had to negate the Y coordinate >>> >>> // Correct winding order: NW → NE → SE → SW >>> // ggb: extrude works in xy plane, rotate and translate to make it >>> 'vertical', >>> // along the wall frame axis, Y. >>> rotate([90,0,-90]) >>> translate([-S,0,-2]) >>> linear_extrude(height = t) >>> polygon(points=[NW, NE, SE, SW]); >>> } >>> >>> T=96; //ggb: how tall is the framing >>> S=28; //ggb: spacing between the framing members >>> >>> translate([0,-2,0])cube([4,2,T]); >>> translate([0,S,0]) cube([4,2,T]); >>> >>> color("green") v2x4_diagonal(S, T); >>> >>> I offer this in the public domain, use as you see fit. All I'd like to >>> get is some sort of explanation as to how it works... >>> >>> Thanks, >>> Glenn Butcher >>> >>> >>> >>> _______________________________________________ >>> OpenSCAD mailing list >>> To unsubscribe send an email to discuss-leave@lists.openscad.org >> >> _______________________________________________ >> OpenSCAD mailing list >> To unsubscribe send an email to discuss-leave@lists.openscad.org > > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org
FH
Father Horton
Tue, Apr 14, 2026 11:36 PM

OpenSCAD is less mainstream so LLMs can mess it up more easily than say
Python or C++. I’ve found on other projects in other languages that it
helps to know at least what a bad implementation looks like and how to
suggest corrections.

On Tue, Apr 14, 2026 at 6:26 PM Leonard Martin Struttmann via Discuss <
discuss@lists.openscad.org> wrote:

Here's what Claude came up with:

module test( S, L, W )
{
inner = sqrt(S * S + L * L - W * W);
factor = (S * inner - L * W) / (S * S - W * W);

face_length  = S * factor;  // d: long diagonal sides
stud_contact = W * factor;  // h: short vertical sides

points = [ [ 0,0 ],
[ 0, stud_contact ],
[ S, L ],
[ S, L-stud_contact ]] ;

rotate( [ 90, 0, 0 ])
rotate( [ 0, 90, 0 ])
linear_extrude(height = 2, center = false, convexity = 10, twist = 0,
slices = 20, scale = 1.0)
polygon(points = points);
}
T=96;  //ggb: how tall is the framing
S=28;  //ggb: spacing between the framing members

translate([0,-2,0])cube([4,2,T]);
translate([0,S,0]) cube([4,2,T]);

#v2x4_diagonal(S, T);

test( S, T, 4 );

On Tue, Apr 14, 2026 at 4:37 PM Glenn Butcher via Discuss <
discuss@lists.openscad.org> wrote:

Leonard,

Ooh, that's helpful.  I've been eyeballing it, didn't notice that
difference in width.

I've been OpenSCAD-ing various building components, roofs (rise:run),
brick arches (span:height), even polygon curves (min-circle), and I've
readily found the requisite math to do such, but this parallelogram has
just stumped me.  Not a fan of this 'vibe coding' thing, but I've tried
'gimme-example' tasks and I've learned about things like OpenGL rendering
that way.  I get your disdain, too easy for folk to just wing it, so I'm
trying not to blindly rely on it for this problem.

Talking about the math, there seems to not be enough information in the
parameters to which I've constrained the problem, for the parallelogram
that would be its height (the 4" board dimension), and the diagonal length
(sqrt(SS + TT)).  Or, am I just too ill-informed to see it.

Regards,
Glenn
Skeptical ex-software person
On 4/14/2026 3:10 PM, Leonard Martin Struttmann via Discuss wrote:

And, on top of that, it doesn't seem to be correct.  When I ran that
code, the diagonal brace turned out to be 2x4.63 instead of the specified
2x4.

On Tue, Apr 14, 2026 at 3:59 PM Ari Diacou via Discuss <
discuss@lists.openscad.org> wrote:

Hi Glenn,

This is a first. I have never seen AI written code before. Thank you for
introducing me to this absolute abomination. You cannot read it because it
is terrible. I haven't run the code, because I'm on my phone, and because
my curiosity of AI hallucinations does not overcome my mistrust of them.
But based on your description, this should be about 8 lines of vector
algebra (I estimate 4 lines of declaration, 4 lines of calculation, and one
line of something like linear_extrude () difference()...)

This is using vector calculus naming conventions for vector algebra.
Like, I can see how it could be right, but I can also see how no programmer
would ever write this garbage*. It took me about a minute to absolutely
fear for civilization if we are firing human programmers in favor of
algorithms that write this garbage*.

*By garbage I of course mean at least 10 explative adjectives followed
by the vilest noun in the readers native language.

Cheers,
A slightly more Luddite ex-physicist.

On Tue, Apr 14, 2026, 3:10 PM Glenn Butcher via Discuss <
discuss@lists.openscad.org> wrote:

Disclaimer: I'm not a math person.

I'm building a CAD model of a vintage railroad baggage car, to help
with
the visualization of design for a restoration project. In modeling the
framing internal to the walls, I need diagonal members between the
verticals; my first module to do that was 'carpenter style', where I
laid the diagonal between two vertical members and used difference() to
cut it.  This required an angle parameter that I had to 'scooch' around
to get the right angle.

What I wanted was a module that just took the height and spacing
numbers
and made a parallelogram to fit and extruded it to the right
thickness.
So, I spent a few forays into the internets, searching for the math to
do that.  And, I just couldn't find it, even the AI search summaries
didn't complete the solution.  I finally gave in to the vibe coding
thing, and took the problem to Microsoft CoPilot, with which I had some
success building an OpenGL renderer.  To describe the problem I used
compass cardinal points to lay out the space, NE, NW, SE, SW to define
the four corners of the parallelogram.  Took 5 iterations to get it
close, and it still was plotting the NE corner on the wrong side of the
Y axis.  I finally just told it to negate that corner's vertical
component, ta-da, works.

Thing is, I do not understand the methodology.  I've inspected the
intermediate variables and I just don't have the math chops to
understand how the vectors yield the parallelogram sides.  Here's the
code:

//algorithm courtesy Microsoft CoPilot:
module v2x4_diagonal(S, T) {
//ggb: diagonal member dimensions
w=4;  //ggb: height of the parallelogram
t=2;

  // Upper edge endpoints
  NW = [0, T];
  SE = [S, 0];

  // Diagonal direction
  dx = S;
  dy = -T;
  L  = sqrt(dx*dx + dy*dy);

  // Perpendicular unit vector (points downward)
  px = -T / L;
  py = -S / L;

  // Offset vector for lower edge
  ox = w * px;
  oy = w * py;

  // Lower edge parametric line: P(t) = NW + (ox, oy) + t*(dx, dy)

  // Intersection with x = 0 → SW
  t0 = -ox / dx;
  SW = [0,
        T + oy + t0 * dy];

  // Intersection with x = S → NE
  t1 = (S - ox) / dx;
  NE = [S,
        -(T + oy + t1 * dy)];  //ggb: I had to negate the Y

coordinate

  // Correct winding order: NW → NE → SE → SW
  // ggb: extrude works in xy plane, rotate and translate to make it

'vertical',
//        along the wall frame axis, Y.
rotate([90,0,-90])
translate([-S,0,-2])
linear_extrude(height = t)
polygon(points=[NW, NE, SE, SW]);
}

T=96;  //ggb: how tall is the framing
S=28;  //ggb: spacing between the framing members

translate([0,-2,0])cube([4,2,T]);
translate([0,S,0]) cube([4,2,T]);

color("green") v2x4_diagonal(S, T);

I offer this in the public domain, use as you see fit.  All I'd like to
get is some sort of explanation as to how it works...

Thanks,
Glenn Butcher


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

OpenSCAD is less mainstream so LLMs can mess it up more easily than say Python or C++. I’ve found on other projects in other languages that it helps to know at least what a bad implementation looks like and how to suggest corrections. On Tue, Apr 14, 2026 at 6:26 PM Leonard Martin Struttmann via Discuss < discuss@lists.openscad.org> wrote: > Here's what Claude came up with: > > module test( S, L, W ) > { > inner = sqrt(S * S + L * L - W * W); > factor = (S * inner - L * W) / (S * S - W * W); > > face_length = S * factor; // d: long diagonal sides > stud_contact = W * factor; // h: short vertical sides > > points = [ [ 0,0 ], > [ 0, stud_contact ], > [ S, L ], > [ S, L-stud_contact ]] ; > > rotate( [ 90, 0, 0 ]) > rotate( [ 0, 90, 0 ]) > linear_extrude(height = 2, center = false, convexity = 10, twist = 0, > slices = 20, scale = 1.0) > polygon(points = points); > } > T=96; //ggb: how tall is the framing > S=28; //ggb: spacing between the framing members > > translate([0,-2,0])cube([4,2,T]); > translate([0,S,0]) cube([4,2,T]); > > #v2x4_diagonal(S, T); > > test( S, T, 4 ); > > > On Tue, Apr 14, 2026 at 4:37 PM Glenn Butcher via Discuss < > discuss@lists.openscad.org> wrote: > >> Leonard, >> >> Ooh, that's helpful. I've been eyeballing it, didn't notice that >> difference in width. >> >> I've been OpenSCAD-ing various building components, roofs (rise:run), >> brick arches (span:height), even polygon curves (min-circle), and I've >> readily found the requisite math to do such, but this parallelogram has >> just stumped me. Not a fan of this 'vibe coding' thing, but I've tried >> 'gimme-example' tasks and I've learned about things like OpenGL rendering >> that way. I get your disdain, too easy for folk to just wing it, so I'm >> trying not to blindly rely on it for this problem. >> >> Talking about the math, there seems to not be enough information in the >> parameters to which I've constrained the problem, for the parallelogram >> that would be its height (the 4" board dimension), and the diagonal length >> (sqrt(S*S + T*T)). Or, am I just too ill-informed to see it. >> >> Regards, >> Glenn >> Skeptical ex-software person >> On 4/14/2026 3:10 PM, Leonard Martin Struttmann via Discuss wrote: >> >> And, on top of that, it doesn't seem to be correct. When I ran that >> code, the diagonal brace turned out to be 2x4.63 instead of the specified >> 2x4. >> >> On Tue, Apr 14, 2026 at 3:59 PM Ari Diacou via Discuss < >> discuss@lists.openscad.org> wrote: >> >>> Hi Glenn, >>> >>> This is a first. I have never seen AI written code before. Thank you for >>> introducing me to this absolute abomination. You cannot read it because it >>> is terrible. I haven't run the code, because I'm on my phone, and because >>> my curiosity of AI hallucinations does not overcome my mistrust of them. >>> But based on your description, this should be about 8 lines of vector >>> algebra (I estimate 4 lines of declaration, 4 lines of calculation, and one >>> line of something like linear_extrude () difference()...) >>> >>> This is using vector calculus naming conventions for vector algebra. >>> Like, I can see how it could be right, but I can also see how no programmer >>> would ever write this garbage*. It took me about a minute to absolutely >>> fear for civilization if we are firing human programmers in favor of >>> algorithms that write this garbage*. >>> >>> *By garbage I of course mean at least 10 explative adjectives followed >>> by the vilest noun in the readers native language. >>> >>> Cheers, >>> A slightly more Luddite ex-physicist. >>> >>> On Tue, Apr 14, 2026, 3:10 PM Glenn Butcher via Discuss < >>> discuss@lists.openscad.org> wrote: >>> >>>> Disclaimer: I'm not a math person. >>>> >>>> I'm building a CAD model of a vintage railroad baggage car, to help >>>> with >>>> the visualization of design for a restoration project. In modeling the >>>> framing internal to the walls, I need diagonal members between the >>>> verticals; my first module to do that was 'carpenter style', where I >>>> laid the diagonal between two vertical members and used difference() to >>>> cut it. This required an angle parameter that I had to 'scooch' around >>>> to get the right angle. >>>> >>>> What I wanted was a module that just took the height and spacing >>>> numbers >>>> and made a parallelogram to fit and extruded it to the right >>>> thickness. >>>> So, I spent a few forays into the internets, searching for the math to >>>> do that. And, I just couldn't find it, even the AI search summaries >>>> didn't complete the solution. I finally gave in to the vibe coding >>>> thing, and took the problem to Microsoft CoPilot, with which I had some >>>> success building an OpenGL renderer. To describe the problem I used >>>> compass cardinal points to lay out the space, NE, NW, SE, SW to define >>>> the four corners of the parallelogram. Took 5 iterations to get it >>>> close, and it still was plotting the NE corner on the wrong side of the >>>> Y axis. I finally just told it to negate that corner's vertical >>>> component, ta-da, works. >>>> >>>> Thing is, I do not understand the methodology. I've inspected the >>>> intermediate variables and I just don't have the math chops to >>>> understand how the vectors yield the parallelogram sides. Here's the >>>> code: >>>> >>>> //algorithm courtesy Microsoft CoPilot: >>>> module v2x4_diagonal(S, T) { >>>> //ggb: diagonal member dimensions >>>> w=4; //ggb: height of the parallelogram >>>> t=2; >>>> >>>> // Upper edge endpoints >>>> NW = [0, T]; >>>> SE = [S, 0]; >>>> >>>> // Diagonal direction >>>> dx = S; >>>> dy = -T; >>>> L = sqrt(dx*dx + dy*dy); >>>> >>>> // Perpendicular unit vector (points downward) >>>> px = -T / L; >>>> py = -S / L; >>>> >>>> // Offset vector for lower edge >>>> ox = w * px; >>>> oy = w * py; >>>> >>>> // Lower edge parametric line: P(t) = NW + (ox, oy) + t*(dx, dy) >>>> >>>> // Intersection with x = 0 → SW >>>> t0 = -ox / dx; >>>> SW = [0, >>>> T + oy + t0 * dy]; >>>> >>>> // Intersection with x = S → NE >>>> t1 = (S - ox) / dx; >>>> NE = [S, >>>> -(T + oy + t1 * dy)]; //ggb: I had to negate the Y >>>> coordinate >>>> >>>> // Correct winding order: NW → NE → SE → SW >>>> // ggb: extrude works in xy plane, rotate and translate to make it >>>> 'vertical', >>>> // along the wall frame axis, Y. >>>> rotate([90,0,-90]) >>>> translate([-S,0,-2]) >>>> linear_extrude(height = t) >>>> polygon(points=[NW, NE, SE, SW]); >>>> } >>>> >>>> T=96; //ggb: how tall is the framing >>>> S=28; //ggb: spacing between the framing members >>>> >>>> translate([0,-2,0])cube([4,2,T]); >>>> translate([0,S,0]) cube([4,2,T]); >>>> >>>> color("green") v2x4_diagonal(S, T); >>>> >>>> I offer this in the public domain, use as you see fit. All I'd like to >>>> get is some sort of explanation as to how it works... >>>> >>>> Thanks, >>>> Glenn Butcher >>>> >>>> >>>> >>>> _______________________________________________ >>>> OpenSCAD mailing list >>>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>> >>> _______________________________________________ >>> OpenSCAD mailing list >>> To unsubscribe send an email to discuss-leave@lists.openscad.org >> >> >> _______________________________________________ >> OpenSCAD mailing list >> To unsubscribe send an email to discuss-leave@lists.openscad.org >> >> _______________________________________________ >> OpenSCAD mailing list >> To unsubscribe send an email to discuss-leave@lists.openscad.org > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org
GB
Glenn Butcher
Wed, Apr 15, 2026 12:01 AM

The claude code gives a precise 4" board, yay.

It also declares and computes face_length, but doesn't use it.  I wonder
the "thought process" behind that...

That said, the behavior of the code is more intuitive, to this
bear-of-little-brain.

But the part I really worry about all this is the effort over and above
what one asks for.  I've got a vintage photo that I wanted to use to
validate mortar lines between stones in a wall, so I fed it to Gemini
(Nano Banana???) with a specific task statement to enhance the mortar
lines.  It first wanted to make the stones bricks; took a few iterations
to talk it into working on the stones actually depicted in the picture. 
But then, it also on its own decided to colorize the black and white
image, and to replace the smudges that were people's faces with faces
from somewhere else.  Wasn't going to trust the mortar lines with that
behavior...

On 4/14/2026 5:26 PM, Leonard Martin Struttmann via Discuss wrote:

Here's what Claude came up with:

module test( S, L, W )
{
  inner = sqrt(S * S + L * L - W * W);
  factor = (S * inner - L * W) / (S * S - W * W);

  face_length  = S * factor;   // d: long diagonal sides
  stud_contact = W * factor;   // h: short vertical sides

  points = [ [ 0,0 ],
    [ 0, stud_contact ],
    [ S, L ],
    [ S, L-stud_contact ]] ;

  rotate( [ 90, 0, 0 ])
  rotate( [ 0, 90, 0 ])
  linear_extrude(height = 2, center = false, convexity = 10, twist =
0, slices = 20, scale = 1.0)
  polygon(points = points);
}
T=96;  //ggb: how tall is the framing
S=28;  //ggb: spacing between the framing members

translate([0,-2,0])cube([4,2,T]);
translate([0,S,0]) cube([4,2,T]);

#v2x4_diagonal(S, T);

test( S, T, 4 );

On Tue, Apr 14, 2026 at 4:37 PM Glenn Butcher via Discuss
discuss@lists.openscad.org wrote:

 Leonard,

 Ooh, that's helpful.  I've been eyeballing it, didn't notice that
 difference in width.

 I've been OpenSCAD-ing various building components, roofs
 (rise:run), brick arches (span:height), even polygon curves
 (min-circle), and I've readily found the requisite math to do
 such, but this parallelogram has just stumped me.  Not a fan of
 this 'vibe coding' thing, but I've tried 'gimme-example' tasks and
 I've learned about things like OpenGL rendering that way.  I get
 your disdain, too easy for folk to just wing it, so I'm trying not
 to blindly rely on it for this problem.

 Talking about the math, there seems to not be enough information
 in the parameters to which I've constrained the problem, for the
 parallelogram that would be its height (the 4" board dimension),
 and the diagonal length (sqrt(S*S + T*T)).  Or, am I just too
 ill-informed to see it.

 Regards,
 Glenn
 Skeptical ex-software person

 On 4/14/2026 3:10 PM, Leonard Martin Struttmann via Discuss wrote:
 And, on top of that, it doesn't seem to be correct.  When I ran
 that code, the diagonal brace turned out to be 2x4.63 instead of
 the specified 2x4.

 On Tue, Apr 14, 2026 at 3:59 PM Ari Diacou via Discuss
 <discuss@lists.openscad.org> wrote:

     Hi Glenn,

     This is a first. I have never seen AI written code before.
     Thank you for introducing me to this absolute abomination.
     You cannot read it because it is terrible. I haven't run the
     code, because I'm on my phone, and because my curiosity of AI
     hallucinations does not overcome my mistrust of them. But
     based on your description, this should be about 8 lines of
     vector algebra (I estimate 4 lines of declaration, 4 lines of
     calculation, and one line of something like linear_extrude ()
     difference()...)

     This is using vector calculus naming conventions for vector
     algebra. Like, I can see how it could be right, but I can
     also see how no programmer would ever write this garbage*. It
     took me about a minute to absolutely fear for civilization if
     we are firing human programmers in favor of algorithms that
     write this garbage*.

     *By garbage I of course mean at least 10 explative adjectives
     followed by the vilest noun in the readers native language.

     Cheers,
     A slightly more Luddite ex-physicist.

     On Tue, Apr 14, 2026, 3:10 PM Glenn Butcher via Discuss
     <discuss@lists.openscad.org> wrote:

         Disclaimer: I'm not a math person.

         I'm building a CAD model of a vintage railroad baggage
         car, to help with
         the visualization of design for a restoration project. In
         modeling the
         framing internal to the walls, I need diagonal members
         between the
         verticals; my first module to do that was 'carpenter
         style', where I
         laid the diagonal between two vertical members and used
         difference() to
         cut it.  This required an angle parameter that I had to
         'scooch' around
         to get the right angle.

         What I wanted was a module that just took the height and
         spacing numbers
         and made a parallelogram to fit and extruded it to the
         right thickness.
         So, I spent a few forays into the internets, searching
         for the math to
         do that.  And, I just couldn't find it, even the AI
         search summaries
         didn't complete the solution.  I finally gave in to the
         vibe coding
         thing, and took the problem to Microsoft CoPilot, with
         which I had some
         success building an OpenGL renderer.  To describe the
         problem I used
         compass cardinal points to lay out the space, NE, NW, SE,
         SW to define
         the four corners of the parallelogram.  Took 5 iterations
         to get it
         close, and it still was plotting the NE corner on the
         wrong side of the
         Y axis.  I finally just told it to negate that corner's
         vertical
         component, ta-da, works.

         Thing is, I do not understand the methodology.  I've
         inspected the
         intermediate variables and I just don't have the math
         chops to
         understand how the vectors yield the parallelogram
         sides.  Here's the code:

         //algorithm courtesy Microsoft CoPilot:
         module v2x4_diagonal(S, T) {
              //ggb: diagonal member dimensions
              w=4;  //ggb: height of the parallelogram
              t=2;

              // Upper edge endpoints
              NW = [0, T];
              SE = [S, 0];

              // Diagonal direction
              dx = S;
              dy = -T;
              L  = sqrt(dx*dx + dy*dy);

              // Perpendicular unit vector (points downward)
              px = -T / L;
              py = -S / L;

              // Offset vector for lower edge
              ox = w * px;
              oy = w * py;

              // Lower edge parametric line: P(t) = NW + (ox, oy)
         + t*(dx, dy)

              // Intersection with x = 0 → SW
              t0 = -ox / dx;
              SW = [0,
                    T + oy + t0 * dy];

              // Intersection with x = S → NE
              t1 = (S - ox) / dx;
              NE = [S,
                    -(T + oy + t1 * dy)];  //ggb: I had to negate
         the Y coordinate

              // Correct winding order: NW → NE → SE → SW
              // ggb: extrude works in xy plane, rotate and
         translate to make it
         'vertical',
              //        along the wall frame axis, Y.
              rotate([90,0,-90])
                  translate([-S,0,-2])
                      linear_extrude(height = t)
                          polygon(points=[NW, NE, SE, SW]);
         }

         T=96;  //ggb: how tall is the framing
         S=28;  //ggb: spacing between the framing members

         translate([0,-2,0])cube([4,2,T]);
         translate([0,S,0]) cube([4,2,T]);

         color("green") v2x4_diagonal(S, T);

         I offer this in the public domain, use as you see fit. 
         All I'd like to
         get is some sort of explanation as to how it works...

         Thanks,
         Glenn Butcher



         _______________________________________________
         OpenSCAD mailing list
         To unsubscribe send an email to
         discuss-leave@lists.openscad.org

     _______________________________________________
     OpenSCAD mailing list
     To unsubscribe send an email to discuss-leave@lists.openscad.org


 _______________________________________________
 OpenSCAD mailing list
 To unsubscribe send an email todiscuss-leave@lists.openscad.org
 _______________________________________________
 OpenSCAD mailing list
 To unsubscribe send an email to discuss-leave@lists.openscad.org

OpenSCAD mailing list
To unsubscribe send an email todiscuss-leave@lists.openscad.org

The claude code gives a precise 4" board, yay. It also declares and computes face_length, but doesn't use it.  I wonder the "thought process" behind that... That said, the behavior of the code is more intuitive, to this bear-of-little-brain. But the part I really worry about all this is the effort over and above what one asks for.  I've got a vintage photo that I wanted to use to validate mortar lines between stones in a wall, so I fed it to Gemini (Nano Banana???) with a specific task statement to enhance the mortar lines.  It first wanted to make the stones bricks; took a few iterations to talk it into working on the stones actually depicted in the picture.  But then, it also on its own decided to colorize the black and white image, and to replace the smudges that were people's faces with faces from somewhere else.  Wasn't going to trust the mortar lines with that behavior... On 4/14/2026 5:26 PM, Leonard Martin Struttmann via Discuss wrote: > Here's what Claude came up with: > > module test( S, L, W ) > { >   inner = sqrt(S * S + L * L - W * W); >   factor = (S * inner - L * W) / (S * S - W * W); > >   face_length  = S * factor;   // d: long diagonal sides >   stud_contact = W * factor;   // h: short vertical sides > >   points = [ [ 0,0 ], >     [ 0, stud_contact ], >     [ S, L ], >     [ S, L-stud_contact ]] ; > >   rotate( [ 90, 0, 0 ]) >   rotate( [ 0, 90, 0 ]) >   linear_extrude(height = 2, center = false, convexity = 10, twist = > 0, slices = 20, scale = 1.0) >   polygon(points = points); > } > T=96;  //ggb: how tall is the framing > S=28;  //ggb: spacing between the framing members > > translate([0,-2,0])cube([4,2,T]); > translate([0,S,0]) cube([4,2,T]); > > #v2x4_diagonal(S, T); > > test( S, T, 4 ); > > > On Tue, Apr 14, 2026 at 4:37 PM Glenn Butcher via Discuss > <discuss@lists.openscad.org> wrote: > > Leonard, > > Ooh, that's helpful.  I've been eyeballing it, didn't notice that > difference in width. > > I've been OpenSCAD-ing various building components, roofs > (rise:run), brick arches (span:height), even polygon curves > (min-circle), and I've readily found the requisite math to do > such, but this parallelogram has just stumped me.  Not a fan of > this 'vibe coding' thing, but I've tried 'gimme-example' tasks and > I've learned about things like OpenGL rendering that way.  I get > your disdain, too easy for folk to just wing it, so I'm trying not > to blindly rely on it for this problem. > > Talking about the math, there seems to not be enough information > in the parameters to which I've constrained the problem, for the > parallelogram that would be its height (the 4" board dimension), > and the diagonal length (sqrt(S*S + T*T)).  Or, am I just too > ill-informed to see it. > > Regards, > Glenn > Skeptical ex-software person > > On 4/14/2026 3:10 PM, Leonard Martin Struttmann via Discuss wrote: >> And, on top of that, it doesn't seem to be correct.  When I ran >> that code, the diagonal brace turned out to be 2x4.63 instead of >> the specified 2x4. >> >> On Tue, Apr 14, 2026 at 3:59 PM Ari Diacou via Discuss >> <discuss@lists.openscad.org> wrote: >> >> Hi Glenn, >> >> This is a first. I have never seen AI written code before. >> Thank you for introducing me to this absolute abomination. >> You cannot read it because it is terrible. I haven't run the >> code, because I'm on my phone, and because my curiosity of AI >> hallucinations does not overcome my mistrust of them. But >> based on your description, this should be about 8 lines of >> vector algebra (I estimate 4 lines of declaration, 4 lines of >> calculation, and one line of something like linear_extrude () >> difference()...) >> >> This is using vector calculus naming conventions for vector >> algebra. Like, I can see how it could be right, but I can >> also see how no programmer would ever write this garbage*. It >> took me about a minute to absolutely fear for civilization if >> we are firing human programmers in favor of algorithms that >> write this garbage*. >> >> *By garbage I of course mean at least 10 explative adjectives >> followed by the vilest noun in the readers native language. >> >> Cheers, >> A slightly more Luddite ex-physicist. >> >> On Tue, Apr 14, 2026, 3:10 PM Glenn Butcher via Discuss >> <discuss@lists.openscad.org> wrote: >> >> Disclaimer: I'm not a math person. >> >> I'm building a CAD model of a vintage railroad baggage >> car, to help with >> the visualization of design for a restoration project. In >> modeling the >> framing internal to the walls, I need diagonal members >> between the >> verticals; my first module to do that was 'carpenter >> style', where I >> laid the diagonal between two vertical members and used >> difference() to >> cut it.  This required an angle parameter that I had to >> 'scooch' around >> to get the right angle. >> >> What I wanted was a module that just took the height and >> spacing numbers >> and made a parallelogram to fit and extruded it to the >> right thickness. >> So, I spent a few forays into the internets, searching >> for the math to >> do that.  And, I just couldn't find it, even the AI >> search summaries >> didn't complete the solution.  I finally gave in to the >> vibe coding >> thing, and took the problem to Microsoft CoPilot, with >> which I had some >> success building an OpenGL renderer.  To describe the >> problem I used >> compass cardinal points to lay out the space, NE, NW, SE, >> SW to define >> the four corners of the parallelogram.  Took 5 iterations >> to get it >> close, and it still was plotting the NE corner on the >> wrong side of the >> Y axis.  I finally just told it to negate that corner's >> vertical >> component, ta-da, works. >> >> Thing is, I do not understand the methodology.  I've >> inspected the >> intermediate variables and I just don't have the math >> chops to >> understand how the vectors yield the parallelogram >> sides.  Here's the code: >> >> //algorithm courtesy Microsoft CoPilot: >> module v2x4_diagonal(S, T) { >>      //ggb: diagonal member dimensions >>      w=4;  //ggb: height of the parallelogram >>      t=2; >> >>      // Upper edge endpoints >>      NW = [0, T]; >>      SE = [S, 0]; >> >>      // Diagonal direction >>      dx = S; >>      dy = -T; >>      L  = sqrt(dx*dx + dy*dy); >> >>      // Perpendicular unit vector (points downward) >>      px = -T / L; >>      py = -S / L; >> >>      // Offset vector for lower edge >>      ox = w * px; >>      oy = w * py; >> >>      // Lower edge parametric line: P(t) = NW + (ox, oy) >> + t*(dx, dy) >> >>      // Intersection with x = 0 → SW >>      t0 = -ox / dx; >>      SW = [0, >>            T + oy + t0 * dy]; >> >>      // Intersection with x = S → NE >>      t1 = (S - ox) / dx; >>      NE = [S, >>            -(T + oy + t1 * dy)];  //ggb: I had to negate >> the Y coordinate >> >>      // Correct winding order: NW → NE → SE → SW >>      // ggb: extrude works in xy plane, rotate and >> translate to make it >> 'vertical', >>      //        along the wall frame axis, Y. >>      rotate([90,0,-90]) >>          translate([-S,0,-2]) >>              linear_extrude(height = t) >>                  polygon(points=[NW, NE, SE, SW]); >> } >> >> T=96;  //ggb: how tall is the framing >> S=28;  //ggb: spacing between the framing members >> >> translate([0,-2,0])cube([4,2,T]); >> translate([0,S,0]) cube([4,2,T]); >> >> color("green") v2x4_diagonal(S, T); >> >> I offer this in the public domain, use as you see fit.  >> All I'd like to >> get is some sort of explanation as to how it works... >> >> Thanks, >> Glenn Butcher >> >> >> >> _______________________________________________ >> OpenSCAD mailing list >> To unsubscribe send an email to >> discuss-leave@lists.openscad.org >> >> _______________________________________________ >> OpenSCAD mailing list >> To unsubscribe send an email to discuss-leave@lists.openscad.org >> >> >> _______________________________________________ >> OpenSCAD mailing list >> To unsubscribe send an email todiscuss-leave@lists.openscad.org > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org > > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email todiscuss-leave@lists.openscad.org
LD
lee.deraud@roadrunner.com
Wed, Apr 15, 2026 12:21 AM

Speaking as someone whose woodworking chops are probably better than his OpenSCAD chops…

Am I the only one chuckling at the idea of a precise 4”-wide 2x4? 😊

(And now for some reason I can’t get the phrase “measure twice, code once” out of my head.)

From: Glenn Butcher via Discuss discuss@lists.openscad.org
Sent: Tuesday, April 14, 2026 5:01 PM
To: discuss@lists.openscad.org
Cc: Glenn Butcher glenn.butcher@gmail.com
Subject: [OpenSCAD] Re: Math Behind the Code

The claude code gives a precise 4" board, yay.

Speaking as someone whose woodworking chops are probably better than his OpenSCAD chops… Am I the only one chuckling at the idea of a precise 4”-wide 2x4? 😊 (And now for some reason I can’t get the phrase “measure twice, code once” out of my head.) From: Glenn Butcher via Discuss <discuss@lists.openscad.org> Sent: Tuesday, April 14, 2026 5:01 PM To: discuss@lists.openscad.org Cc: Glenn Butcher <glenn.butcher@gmail.com> Subject: [OpenSCAD] Re: Math Behind the Code The claude code gives a precise 4" board, yay.
LM
Leonard Martin Struttmann
Wed, Apr 15, 2026 12:30 AM

The Claude code computes face_length because I told it to.  Actually, I
first had Claude create a Python function to compute those values.  I then
hand-converted that to OpenSCAD.

On Tue, Apr 14, 2026 at 7:21 PM Lee DeRaud via Discuss <
discuss@lists.openscad.org> wrote:

Speaking as someone whose woodworking chops are probably better than his
OpenSCAD chops…

Am I the only one chuckling at the idea of a precise 4”-wide 2x4? 😊

(And now for some reason I can’t get the phrase “measure twice, code once”
out of my head.)

From: Glenn Butcher via Discuss discuss@lists.openscad.org
Sent: Tuesday, April 14, 2026 5:01 PM
To: discuss@lists.openscad.org
Cc: Glenn Butcher glenn.butcher@gmail.com
Subject: [OpenSCAD] Re: Math Behind the Code

The claude code gives a precise 4" board, yay.


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

The Claude code computes face_length because I told it to. Actually, I first had Claude create a Python function to compute those values. I then hand-converted that to OpenSCAD. On Tue, Apr 14, 2026 at 7:21 PM Lee DeRaud via Discuss < discuss@lists.openscad.org> wrote: > Speaking as someone whose woodworking chops are probably better than his > OpenSCAD chops… > > Am I the only one chuckling at the idea of a precise 4”-wide 2x4? 😊 > > (And now for some reason I can’t get the phrase “measure twice, code once” > out of my head.) > > > > *From:* Glenn Butcher via Discuss <discuss@lists.openscad.org> > *Sent:* Tuesday, April 14, 2026 5:01 PM > *To:* discuss@lists.openscad.org > *Cc:* Glenn Butcher <glenn.butcher@gmail.com> > *Subject:* [OpenSCAD] Re: Math Behind the Code > > > > The claude code gives a precise 4" board, yay. > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org >
GB
Glenn Butcher
Wed, Apr 15, 2026 12:36 AM

The baggage car we're restoring was built in 1880, when a 2x4 was
actually 2x4. We work with a sawmill in Antonito, CO that'll cut what we
need.

Yeah, I was a shade-tree framing/finish carpenter when I started working
with this, found out there's a third category...

Glenn Butcher
Sr. Paint Removal Engineer
Friends of the Cumbres & Toltec Scenic Railroad

On 4/14/2026 6:21 PM, Lee DeRaud via Discuss wrote:

Speaking as someone whose woodworking chops are probably better than
his OpenSCAD chops…

Am I the only one chuckling at the idea of a precise 4”-wide 2x4? 😊

(And now for some reason I can’t get the phrase “measure twice, code
once” out of my head.)

*From:*Glenn Butcher via Discuss discuss@lists.openscad.org
Sent: Tuesday, April 14, 2026 5:01 PM
To: discuss@lists.openscad.org
Cc: Glenn Butcher glenn.butcher@gmail.com
Subject: [OpenSCAD] Re: Math Behind the Code

The claude code gives a precise 4" board, yay.


OpenSCAD mailing list
To unsubscribe send an email todiscuss-leave@lists.openscad.org

The baggage car we're restoring was built in 1880, when a 2x4 was actually 2x4. We work with a sawmill in Antonito, CO that'll cut what we need. Yeah, I was a shade-tree framing/finish carpenter when I started working with this, found out there's a third category... Glenn Butcher Sr. Paint Removal Engineer Friends of the Cumbres & Toltec Scenic Railroad On 4/14/2026 6:21 PM, Lee DeRaud via Discuss wrote: > > Speaking as someone whose woodworking chops are probably better than > his OpenSCAD chops… > > Am I the only one chuckling at the idea of a precise 4”-wide 2x4? 😊 > > (And now for some reason I can’t get the phrase “measure twice, code > once” out of my head.) > > *From:*Glenn Butcher via Discuss <discuss@lists.openscad.org> > *Sent:* Tuesday, April 14, 2026 5:01 PM > *To:* discuss@lists.openscad.org > *Cc:* Glenn Butcher <glenn.butcher@gmail.com> > *Subject:* [OpenSCAD] Re: Math Behind the Code > > The claude code gives a precise 4" board, yay. > > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email todiscuss-leave@lists.openscad.org