1
0
mirror of https://github.com/Irev-Dev/Round-Anything.git synced 2025-01-17 02:58:14 +01:00

Merge pull request #5 from Irev-Dev/add-docs-for-polyRoundExtrude

Add docs and examples for ployRoundExtrude
This commit is contained in:
Kurt Hutten 2020-08-09 20:45:29 +10:00 committed by GitHub
commit 3f9d124bb7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 95 additions and 41 deletions

View File

@ -12,7 +12,13 @@ function translate3Dcoords(points,tran=[0,0,0],mult=[1,1,1])=[for(i=[0:len(point
(points[i].y*mult.y)+tran.y, (points[i].y*mult.y)+tran.y,
(points[i].z*mult.z)+tran.z (points[i].z*mult.z)+tran.z
]]; ]];
function offsetPoints(points, offset=0)= function offsetPolygonPoints(points, offset=0)=
// Work sthe same as the offset does, except for the fact that instead of a 2d shape
// It works directly on ploygon points
// it returns the same number of points just offset into or, away from the original shape.
// points= a series of x,y points[[x1,y1],[x2,y2],...]
// offset= amount to offset by, negative numbers go inwards into the shape, positive numbers go out
// return= a series of x,y points[[x1,y1],[x2,y2],...]
let( let(
isCWorCCW=sign(offset)*CWorCCW(points)*-1, isCWorCCW=sign(offset)*CWorCCW(points)*-1,
lp=len(points) lp=len(points)
@ -23,18 +29,25 @@ let(
points[listWrap(i+1,lp)], points[listWrap(i+1,lp)],
],thick=offset,mode=isCWorCCW)]; ],thick=offset,mode=isCWorCCW)];
function curvePolygon(points,r,fn,minR=0.01)= function makeCurvedPartOfPolyHedron(radiiPoints,r,fn,minR=0.01)=
// this is a private function that I'm not expecting library users to use directly
// radiiPoints= serise of x, y, r points
// r= radius of curve that will be put on the end of the extrusion
// fn= amount of subdivisions
// minR= if one of the points in radiiPoints is less than r, it's likely to converg and form a sharp edge,
// the min radius on this these converge edges can be controled with minR, though because of legacy reasons it can't be 0, but can be a very small number.
// return= array of [polyhedronPoints, Polyhedronfaces, theLength of a singe layer in the curve]
let( let(
lp=len(points), lp=len(radiiPoints),
radii=[for(i=[0:lp-1])points[i].z], radii=[for(i=[0:lp-1])radiiPoints[i].z],
isCWorCCWOverall=CWorCCW(points), isCWorCCWOverall=CWorCCW(radiiPoints),
dir=sign(r), dir=sign(r),
absR=abs(r), absR=abs(r),
fractionOffLp=1-1/fn, fractionOffLp=1-1/fn,
allPoints=[for(fraction=[0:1/fn:1]) allPoints=[for(fraction=[0:1/fn:1])
let( let(
iterationOffset=dir*sqrt(sq(absR)-sq(fraction*absR))-dir*absR, iterationOffset=dir*sqrt(sq(absR)-sq(fraction*absR))-dir*absR,
theOffsetPoints=offsetPoints(points,iterationOffset), theOffsetPoints=offsetPolygonPoints(radiiPoints,iterationOffset),
polyRoundOffsetPoints=[for(i=[0:lp-1]) polyRoundOffsetPoints=[for(i=[0:lp-1])
let( let(
pointsAboutCurrent=[ pointsAboutCurrent=[
@ -52,70 +65,104 @@ let(
) )
[theOffsetPoints[i].x, theOffsetPoints[i].y, isInternalRadius? increasingRadius: decreasingRadius] [theOffsetPoints[i].x, theOffsetPoints[i].y, isInternalRadius? increasingRadius: decreasingRadius]
], ],
newPoints=polyRound(polyRoundOffsetPoints,fn) pointsForThisLayer=polyRound(polyRoundOffsetPoints,fn)
) )
addZcoord(newPoints,fraction*absR) addZcoord(pointsForThisLayer,fraction*absR)
], ],
allPointsFlat=flatternArray(allPoints), polyhedronPoints=flatternArray(allPoints),
allLp=len(allPoints), allLp=len(allPoints),
newLp=len(allPoints[0]), layerLength=len(allPoints[0]),
loopToSecondLastLayer=allLp-2, loopToSecondLastLayer=allLp-2,
sideFaces=[for(layerIndex=[0:loopToSecondLastLayer])let( sideFaces=[for(layerIndex=[0:loopToSecondLastLayer])let(
currentLayeroffset=layerIndex*newLp, currentLayeroffset=layerIndex*layerLength,
nextLayeroffset=(layerIndex+1)*newLp, nextLayeroffset=(layerIndex+1)*layerLength,
layerFaces=[for(subLayerIndex=[0:newLp-1]) layerFaces=[for(subLayerIndex=[0:layerLength-1])
[ [
currentLayeroffset+subLayerIndex, currentLayeroffset + listWrap(subLayerIndex+1,newLp), nextLayeroffset+listWrap(subLayerIndex+1,newLp), nextLayeroffset+subLayerIndex] currentLayeroffset+subLayerIndex, currentLayeroffset + listWrap(subLayerIndex+1,layerLength), nextLayeroffset+listWrap(subLayerIndex+1,layerLength), nextLayeroffset+subLayerIndex]
] ]
)layerFaces] )layerFaces],
polyhedronFaces=flatternArray(sideFaces)
) )
[allPointsFlat,flatternArray(sideFaces),newLp]; [polyhedronPoints, polyhedronFaces, layerLength];
function flatternRecursion(array, init=[], currentIndex)= function flatternRecursion(array, init=[], currentIndex)=
// this is a private function, init and currentIndex are for the function
// only for when it's calling itself, which is why there is a simplified version flatternArray that just calls this one
// array= array to flattern by one level of nesting
// init= the array used to cancat with the next call, only for when the function calls itself
// currentIndex= so the function can keep track of how far it's progressed through the array, only for when it's calling itself
// returns= flatterned array, by one level of nesting
let( let(
shouldKickOffRecursion=currentIndex==undef?1:0, shouldKickOffRecursion=currentIndex==undef?1:0,
isLastIndex=currentIndex+1==len(array)?1:0, isLastIndex=currentIndex+1==len(array)?1:0,
result=shouldKickOffRecursion?flatternRecursion(array,[],0): flatArray=shouldKickOffRecursion?flatternRecursion(array,[],0):
isLastIndex?concat(init,array[currentIndex]): isLastIndex?concat(init,array[currentIndex]):
flatternRecursion(array,concat(init,array[currentIndex]),currentIndex+1) flatternRecursion(array,concat(init,array[currentIndex]),currentIndex+1)
) )
result; flatArray;
function flatternArray(array)=flatternRecursion(array);
function flatternArray(array)=
// public version of flatternRecursion, has simplified params to avoid confusion
// array= array to be flatterned
// return= array that been flatterend by one level of nesting
flatternRecursion(array);
function offsetAllFacesBy(array,offset)=[ function offsetAllFacesBy(array,offset)=[
// polyhedron faces are simply a list of indeices to points, if your concat points together than you probably need to offset
// your faces array to points to the right place in the new list
// array= array of point indicies
// offset= number to offset all indecies by
// return= array of point indices (i.e. faces) with offset applied
for(faceIndex=[0:len(array)-1])[ for(faceIndex=[0:len(array)-1])[
for(pointIndex=[0:len(array[faceIndex])-1])array[faceIndex][pointIndex]+offset for(pointIndex=[0:len(array[faceIndex])-1])array[faceIndex][pointIndex]+offset
] ]
]; ];
function extrudePolygonWithRadius(points,h=5,r1=1,r2=1,steps=4)= function extrudePolygonWithRadius(radiiPoints,h=5,r1=1,r2=1,fn=4)=
// this basically calls makeCurvedPartOfPolyHedron twice to get the curved section of the final polyhedron
// and then goes about assmbling them, as the side faces and the top and bottom faces are missing
// radiiPoints= series of [x,y,r] points,
// h= height of the extrude (total including radius sections)
// r1,r2= define the radius at the top and bottom of the extrud respectively, negative number flange out the extrude
// fn= number of subdivisions
// returns= [polyhedronPoints, polyhedronFaces]
let( let(
lp=len(points), // top is the top curved part of the extrude
top=curvePolygon(points,r1,steps), top=makeCurvedPartOfPolyHedron(radiiPoints,r1,fn),
topPoints=translate3Dcoords(top[0],[0,0,h-r1]), topRadiusPoints=translate3Dcoords(top[0],[0,0,h-r1]),
roundedLp=top[2], singeLayerLength=top[2],
topFaces=top[1], topRadiusFaces=top[1],
topPointsL=len(topPoints), radiusPointsLength=len(topRadiusPoints), // is the same length as bottomRadiusPoints
bottom=curvePolygon(points,r2,steps), // bottom is the bottom curved part of the extrude
bottomPoints=translate3Dcoords(bottom[0],[0,0,abs(r2)],[1,1,-1]), bottom=makeCurvedPartOfPolyHedron(radiiPoints,r2,fn),
bottomFaces=offsetAllFacesBy(bottom[1],topPointsL), // Z axis needs to be multiplied by -1 to flip it so the radius is going in the right direction [1,1,-1]
sideFaces=[for(i=[0:roundedLp-1])[ bottomRadiusPoints=translate3Dcoords(bottom[0],[0,0,abs(r2)],[1,1,-1]),
// becaues the points will be all concatenated into the same array, and the bottom points come second, than
// the original indices the faces are points towards are wrong and need to have an offset applied to them
bottomRadiusFaces=offsetAllFacesBy(bottom[1],radiusPointsLength),
// all of the side panel of the extrusion, connecting points from the inner layers of each
// of the curved sections
sideFaces=[for(i=[0:singeLayerLength-1])[
i, i,
listWrap(i+1,roundedLp), listWrap(i+1,singeLayerLength),
topPointsL + listWrap(i+1,roundedLp), radiusPointsLength + listWrap(i+1,singeLayerLength),
topPointsL + i radiusPointsLength + i
]], ]],
topCapFace=[for(i=[0:roundedLp-1])topPointsL-roundedLp+i], // both of these caps are simple every point from the last layer of the radius points
bottomCapFace=[for(i=[0:roundedLp-1])topPointsL*2-roundedLp+i] topCapFace=[for(i=[0:singeLayerLength-1])radiusPointsLength-singeLayerLength+i],
bottomCapFace=[for(i=[0:singeLayerLength-1])radiusPointsLength*2-singeLayerLength+i],
finalPolyhedronPoints=concat(topRadiusPoints,bottomRadiusPoints),
finalPolyhedronFaces=concat(topRadiusFaces,bottomRadiusFaces, sideFaces, [topCapFace], [bottomCapFace])
) )
[ [
concat(topPoints,bottomPoints), finalPolyhedronPoints,
concat(topFaces,bottomFaces, sideFaces, [topCapFace], [bottomCapFace]) finalPolyhedronFaces
]; ];
//example of polyRoundhedron thing, fix up soon with proper example.
// radiiPointsbrah=[[10,0,10],[20,20,1.1],[8,7,10],[0,7,0.3],[5,3,0.1],[-4,0,1]]; module polyRoundExtrude(radiiPoints,h=5,r1=1,r2=1,fn=10,convexity=10) {
// wow2=extrudePolygonWithRadius(radiiPointsbrah,2,0.5,-0.8,steps=30); polyhedronPointsNFaces=extrudePolygonWithRadius(radiiPoints,h,r1,r2,fn);
// polyhedron(points=wow2[0], faces=wow2[1], convexity=10); polyhedron(points=polyhedronPointsNFaces[0], faces=polyhedronPointsNFaces[1], convexity=convexity);
}
// testingInternals(); // testingInternals();

View File

@ -9,6 +9,8 @@ basicPolyRoundExample();
// beamChainExample(); // beamChainExample();
// mirrorPointsExample(); // mirrorPointsExample();
// radiusExtrudeExample(); // radiusExtrudeExample();
// radiusExtrudePolygon();
// polyRoundExtrudeExample();
module basicPolyRoundExample(){ module basicPolyRoundExample(){
radiiPoints=[[-4,0,1],[5,3,1.5],[0,7,0.1],[8,7,10],[20,20,0.8],[10,0,10]]; radiiPoints=[[-4,0,1],[5,3,1.5],[0,7,0.1],[8,7,10],[20,20,0.8],[10,0,10]];
@ -200,6 +202,11 @@ module radiusExtrudeExample(){
#translate([7,4,3])extrudeWithRadius(3,-0.5,0.95,50)circle(1,$fn=30); #translate([7,4,3])extrudeWithRadius(3,-0.5,0.95,50)circle(1,$fn=30);
} }
module polyRoundExtrudeExample(){
radiiPointsbrah=[[10,0,10],[20,20,1.1],[8,7,10],[0,7,0.3],[5,3,0.1],[-4,0,1]];
polyRoundExtrude(radiiPointsbrah,2,0.5,-0.8,fn=8);
}
module gridpattern(memberW = 4, sqW = 12, iter = 5, r = 3){ module gridpattern(memberW = 4, sqW = 12, iter = 5, r = 3){
round2d(0, r)rotate([0, 0, 45])translate([-(iter * (sqW + memberW) + memberW) / 2, -(iter * (sqW + memberW) + memberW) / 2])difference(){ round2d(0, r)rotate([0, 0, 45])translate([-(iter * (sqW + memberW) + memberW) / 2, -(iter * (sqW + memberW) + memberW) / 2])difference(){
square([(iter) * (sqW + memberW) + memberW, (iter) * (sqW + memberW) + memberW]); square([(iter) * (sqW + memberW) + memberW, (iter) * (sqW + memberW) + memberW]);