discuss@lists.openscad.org

OpenSCAD general discussion Mailing-list

View all threads

Slice a cube give three points

T
ThumbOne
Sat, Apr 25, 2020 4:33 AM

Really liking the programmatic style of OpenSCAD.

But it does pose some challenges.

If I make a cube:

cube([x, y, z], false);

Given thee points:

p1 = [x1, y1, z1];
p2 = [x2, y2, z2];
p3 = [x3, y3, z3];

that define a plane. I'd like to chop the cube with that plane (everything
above that plane, i.e. z > z_plane).

Clearly one way to do this is is to create another cube, somewhat bigger
perhaps, rotate it, translate it and then use it in a difference.

The specifics are challenging. Has anyone any tips here or code already
written?

For example to define a cube with specified dimensions whose base contains
the three points? That would be a gem!

--
Sent from: http://forum.openscad.org/

Really liking the programmatic style of OpenSCAD. But it does pose some challenges. If I make a cube: cube([x, y, z], false); Given thee points: p1 = [x1, y1, z1]; p2 = [x2, y2, z2]; p3 = [x3, y3, z3]; that define a plane. I'd like to chop the cube with that plane (everything above that plane, i.e. z > z_plane). Clearly one way to do this is is to create another cube, somewhat bigger perhaps, rotate it, translate it and then use it in a difference. The specifics are challenging. Has anyone any tips here or code already written? For example to define a cube with specified dimensions whose base contains the three points? That would be a gem! -- Sent from: http://forum.openscad.org/
RD
Revar Desmera
Sat, Apr 25, 2020 5:24 AM

Off the top of my head, given p1, p2, p3, and a size s that is the size of the largest axis of the part to mask:

    v1 = p2 - p1;
    v2 = p3 - p1;
    n = cross(v1,v2);
    n2 = n / norm(n);
    cp = (p1 + p2 + p3) / 3;
    axis = cross([0,0,1],n);
    ang = acos([0,0,1]*n2);  // Works because n2 is unit length.
    difference() {
        YOUR_PART();
        translate(cp) rotate(a=ang,v=axis) translate([0,0,-2*s]) cube(4*s,center=true);
    }

Or, in BOSL2:

    plane = plane3pt(p1,p2,p3)
    half_of(v=plane_normal(plane), cp=mean([p1,p2,p3]), s=2*s) YOUR_PART();
  • Revar

On Apr 24, 2020, at 9:33 PM, ThumbOne via Discuss discuss@lists.openscad.org wrote:

Really liking the programmatic style of OpenSCAD.

But it does pose some challenges.

If I make a cube:

cube([x, y, z], false);

Given thee points:

p1 = [x1, y1, z1];
p2 = [x2, y2, z2];
p3 = [x3, y3, z3];

that define a plane. I'd like to chop the cube with that plane (everything
above that plane, i.e. z > z_plane).

Clearly one way to do this is is to create another cube, somewhat bigger
perhaps, rotate it, translate it and then use it in a difference.

The specifics are challenging. Has anyone any tips here or code already
written?

For example to define a cube with specified dimensions whose base contains
the three points? That would be a gem!

--
Sent from: http://forum.openscad.org/


OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

Off the top of my head, given p1, p2, p3, and a size s that is the size of the largest axis of the part to mask: ``` v1 = p2 - p1; v2 = p3 - p1; n = cross(v1,v2); n2 = n / norm(n); cp = (p1 + p2 + p3) / 3; axis = cross([0,0,1],n); ang = acos([0,0,1]*n2); // Works because n2 is unit length. difference() { YOUR_PART(); translate(cp) rotate(a=ang,v=axis) translate([0,0,-2*s]) cube(4*s,center=true); } ``` Or, in BOSL2: ``` plane = plane3pt(p1,p2,p3) half_of(v=plane_normal(plane), cp=mean([p1,p2,p3]), s=2*s) YOUR_PART(); ``` - Revar > On Apr 24, 2020, at 9:33 PM, ThumbOne via Discuss <discuss@lists.openscad.org> wrote: > > Really liking the programmatic style of OpenSCAD. > > But it does pose some challenges. > > If I make a cube: > > cube([x, y, z], false); > > Given thee points: > > p1 = [x1, y1, z1]; > p2 = [x2, y2, z2]; > p3 = [x3, y3, z3]; > > that define a plane. I'd like to chop the cube with that plane (everything > above that plane, i.e. z > z_plane). > > Clearly one way to do this is is to create another cube, somewhat bigger > perhaps, rotate it, translate it and then use it in a difference. > > The specifics are challenging. Has anyone any tips here or code already > written? > > For example to define a cube with specified dimensions whose base contains > the three points? That would be a gem! > > > > -- > Sent from: http://forum.openscad.org/ > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
RD
Revar Desmera
Sat, Apr 25, 2020 6:29 AM

Modularized and tested:

module above_plane(p1,p2,p3,s=100) {
	v1 = p2 - p1;
	v2 = p3 - p1;
	n = cross(v1,v2);
	n2 = n / norm(n) * sign(n.z);
	cp = (p1 + p2 + p3) / 3;
	axis = cross([0,0,1],n2);
	dot = [0,0,1] * n2;
	ang = acos(dot>1? 1 : dot<-1? -1 : dot); // Fixes FP rounding errors.
	difference() {
		children();
		translate(cp) rotate(a=ang,v=axis) translate([0,0,-2*s]) cube(4*s,center=true);
	}
}

p1 = [-100,-100,0];
p2 = [0,100,50];
p3 = [100,-100,0];
above_plane(p1,p2,p3) cylinder(h=100,d=100);

On Apr 24, 2020, at 10:24 PM, Revar Desmera revarbat@gmail.com wrote:

Off the top of my head, given p1, p2, p3, and a size s that is the size of the largest axis of the part to mask:

   v1 = p2 - p1;
   v2 = p3 - p1;
   n = cross(v1,v2);
   n2 = n / norm(n);
   cp = (p1 + p2 + p3) / 3;
   axis = cross([0,0,1],n);
   ang = acos([0,0,1]*n2);  // Works because n2 is unit length.
   difference() {
       YOUR_PART();
       translate(cp) rotate(a=ang,v=axis) translate([0,0,-2*s]) cube(4*s,center=true);
   }

Or, in BOSL2:

   plane = plane3pt(p1,p2,p3)
   half_of(v=plane_normal(plane), cp=mean([p1,p2,p3]), s=2*s) YOUR_PART();
  • Revar

On Apr 24, 2020, at 9:33 PM, ThumbOne via Discuss discuss@lists.openscad.org wrote:

Really liking the programmatic style of OpenSCAD.

But it does pose some challenges.

If I make a cube:

cube([x, y, z], false);

Given thee points:

p1 = [x1, y1, z1];
p2 = [x2, y2, z2];
p3 = [x3, y3, z3];

that define a plane. I'd like to chop the cube with that plane (everything
above that plane, i.e. z > z_plane).

Clearly one way to do this is is to create another cube, somewhat bigger
perhaps, rotate it, translate it and then use it in a difference.

The specifics are challenging. Has anyone any tips here or code already
written?

For example to define a cube with specified dimensions whose base contains
the three points? That would be a gem!

--
Sent from: http://forum.openscad.org/


OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

Modularized and tested: ``` module above_plane(p1,p2,p3,s=100) { v1 = p2 - p1; v2 = p3 - p1; n = cross(v1,v2); n2 = n / norm(n) * sign(n.z); cp = (p1 + p2 + p3) / 3; axis = cross([0,0,1],n2); dot = [0,0,1] * n2; ang = acos(dot>1? 1 : dot<-1? -1 : dot); // Fixes FP rounding errors. difference() { children(); translate(cp) rotate(a=ang,v=axis) translate([0,0,-2*s]) cube(4*s,center=true); } } p1 = [-100,-100,0]; p2 = [0,100,50]; p3 = [100,-100,0]; above_plane(p1,p2,p3) cylinder(h=100,d=100); ``` > On Apr 24, 2020, at 10:24 PM, Revar Desmera <revarbat@gmail.com> wrote: > > Off the top of my head, given p1, p2, p3, and a size s that is the size of the largest axis of the part to mask: > > ``` > v1 = p2 - p1; > v2 = p3 - p1; > n = cross(v1,v2); > n2 = n / norm(n); > cp = (p1 + p2 + p3) / 3; > axis = cross([0,0,1],n); > ang = acos([0,0,1]*n2); // Works because n2 is unit length. > difference() { > YOUR_PART(); > translate(cp) rotate(a=ang,v=axis) translate([0,0,-2*s]) cube(4*s,center=true); > } > ``` > > Or, in BOSL2: > ``` > plane = plane3pt(p1,p2,p3) > half_of(v=plane_normal(plane), cp=mean([p1,p2,p3]), s=2*s) YOUR_PART(); > ``` > > - Revar > > > >> On Apr 24, 2020, at 9:33 PM, ThumbOne via Discuss <discuss@lists.openscad.org> wrote: >> >> Really liking the programmatic style of OpenSCAD. >> >> But it does pose some challenges. >> >> If I make a cube: >> >> cube([x, y, z], false); >> >> Given thee points: >> >> p1 = [x1, y1, z1]; >> p2 = [x2, y2, z2]; >> p3 = [x3, y3, z3]; >> >> that define a plane. I'd like to chop the cube with that plane (everything >> above that plane, i.e. z > z_plane). >> >> Clearly one way to do this is is to create another cube, somewhat bigger >> perhaps, rotate it, translate it and then use it in a difference. >> >> The specifics are challenging. Has anyone any tips here or code already >> written? >> >> For example to define a cube with specified dimensions whose base contains >> the three points? That would be a gem! >> >> >> >> -- >> Sent from: http://forum.openscad.org/ >> >> _______________________________________________ >> OpenSCAD mailing list >> Discuss@lists.openscad.org >> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >
RP
Ronaldo Persiano
Sat, Apr 25, 2020 11:46 AM

I would use rotFromTo bellow to rotate the cube from the vertical direction
to the three point plane normal:

p = [[0,0,0] , [10,0,-20], [-30,20,10] ];

cubeOnThreePoints(p);

module cubeOnThreePoints(p) {
norml = (cross(p[0]-p[1],p[0]-p[2]));
normal = sign(norml.z)*norml;

size = max(norm(p[0]-p[1]),norm(p[1]-p[2]),norm(p[0]-p[2]))sqrt(2);
translate((p[0]+p[1]+p[2])/3 ) // center at the baricenter
rotFromTo([0,0,1],normal)
translate(-size
[1,1,0]/2)
cube(size);
// just to illustration
color("blue")
for(pi=p) translate(pi) cube(1,center=true);

}

// minimum rotation that brings direction di to direction do
module rotFromTo(di,do)
if( norm(di-do)==0 || norm(di)==0 || norm(do)==0 )
children();
else
mirror(do/norm(do)+di/norm(di)) mirror(di) children();

Em sáb., 25 de abr. de 2020 às 05:34, ThumbOne via Discuss <
discuss@lists.openscad.org> escreveu:

Really liking the programmatic style of OpenSCAD.

But it does pose some challenges.

If I make a cube:

cube([x, y, z], false);

Given thee points:

p1 = [x1, y1, z1];
p2 = [x2, y2, z2];
p3 = [x3, y3, z3];

that define a plane. I'd like to chop the cube with that plane (everything
above that plane, i.e. z > z_plane).

Clearly one way to do this is is to create another cube, somewhat bigger
perhaps, rotate it, translate it and then use it in a difference.

The specifics are challenging. Has anyone any tips here or code already
written?

For example to define a cube with specified dimensions whose base contains
the three points? That would be a gem!

--
Sent from: http://forum.openscad.org/


OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

I would use rotFromTo bellow to rotate the cube from the vertical direction to the three point plane normal: p = [[0,0,0] , [10,0,-20], [-30,20,10] ]; cubeOnThreePoints(p); module cubeOnThreePoints(p) { norml = (cross(p[0]-p[1],p[0]-p[2])); normal = sign(norml.z)*norml; size = max(norm(p[0]-p[1]),norm(p[1]-p[2]),norm(p[0]-p[2]))*sqrt(2); translate((p[0]+p[1]+p[2])/3 ) // center at the baricenter rotFromTo([0,0,1],normal) translate(-size*[1,1,0]/2) cube(size); // just to illustration color("blue") for(pi=p) translate(pi) cube(1,center=true); } // minimum rotation that brings direction di to direction do module rotFromTo(di,do) if( norm(di-do)==0 || norm(di)==0 || norm(do)==0 ) children(); else mirror(do/norm(do)+di/norm(di)) mirror(di) children(); Em sáb., 25 de abr. de 2020 às 05:34, ThumbOne via Discuss < discuss@lists.openscad.org> escreveu: > Really liking the programmatic style of OpenSCAD. > > But it does pose some challenges. > > If I make a cube: > > cube([x, y, z], false); > > Given thee points: > > p1 = [x1, y1, z1]; > p2 = [x2, y2, z2]; > p3 = [x3, y3, z3]; > > that define a plane. I'd like to chop the cube with that plane (everything > above that plane, i.e. z > z_plane). > > Clearly one way to do this is is to create another cube, somewhat bigger > perhaps, rotate it, translate it and then use it in a difference. > > The specifics are challenging. Has anyone any tips here or code already > written? > > For example to define a cube with specified dimensions whose base contains > the three points? That would be a gem! > > > > -- > Sent from: http://forum.openscad.org/ > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >