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