1
0
mirror of https://github.com/Irev-Dev/Round-Anything.git synced 2025-09-30 17:08:59 +02:00

14 Commits
1.0.1 ... 1.0.3

Author SHA1 Message Date
Kurt Hutten
a6999a7202 Issue-16 Fix 90 degree bug in find findPoint
Actually very similar to issue-11, but I just didn't solve it 100%
2020-11-02 18:12:17 +11:00
Kurt Hutten
a85e6ffd48 Merge pull request #15 from Irev-Dev/irevdev/add-test-geometries
Add test geometries
2020-10-06 06:23:22 +11:00
Kurt Hutten
5a7b6db0ec Add test geometries
After pr #10, it makes sense to have some test shapes beyond the
examples to make sure there aren't regressions in the library,
Hopefully we'll add to this with time.
2020-10-06 06:21:28 +11:00
Kurt Hutten
6b16407430 Merge pull request #14 from Irev-Dev/irevdev/keep-polyround-extrude-height-consistent
Keep polyRound extrude height consistent
2020-10-06 05:41:33 +11:00
Kurt Hutten
9613a81f15 Keep polyRound extrude height consistent
when r1 changed between a positive and negative radius the height
of the extrude would change
2020-10-06 05:39:58 +11:00
Kurt Hutten
e6d67b6304 Merge pull request #10 from nickcoutsos/master
Invert flipped faces for polyRoundExtrude
2020-10-06 05:33:31 +11:00
Nick Coutsos
8d5b6a180b Normalize order of radiiPoints in polyRoundExtrude call 2020-10-05 12:48:31 -04:00
Kurt Hutten
0697444270 Merge pull request #13 from Irev-Dev/irevdev-fix-find-point-to-deal-with-90-deg-angles
Fix findPoint to deal with 90 degree angles
2020-10-05 20:45:11 +11:00
Kurt Hutten
764b3b7a73 Fix findPoint to deal with 90 degree angles
because tan(90) results in inf, some conditions were needed for these
cases
2020-10-05 20:41:30 +11:00
Nick Coutsos
a3934972b5 Invert flipped faces 2020-10-03 22:52:43 -04:00
Kurt Hutten
cb9e7f7b30 Merge pull request #9 from Irev-Dev/update-readme-to-include-video
update readme to include video
2020-08-24 17:55:21 +10:00
Kurt Hutten
1f15acb04b update readme to include video 2020-08-24 17:54:47 +10:00
Kurt Hutten
ddbb97b5ee Merge pull request #8 from Irev-Dev/remove-warnings-and-tweak-examples
Resolve warning messages and tweak examples
2020-08-17 05:46:42 +10:00
Kurt Hutten
40a14892f2 Resolve warning messages and tweak examples 2020-08-17 05:45:47 +10:00
3 changed files with 123 additions and 39 deletions

View File

@@ -10,7 +10,11 @@ The truth is radii, internal radii in particular can be a real pain to add in op
## Documentation
[Here is an overview of the library's features](https://kurthutten.com/blog/round-anything-a-pragmatic-approach-to-openscad-design/).
See an overview of the library in [video form](https://www.youtube.com/watch?v=laxv2wFKq8Q)
<a href="https://www.youtube.com/watch?v=laxv2wFKq8Q"><img src="https://i.ytimg.com/vi/laxv2wFKq8Q/sddefault.jpg" width="100%" align="left"></a>
[Written overview](https://kurthutten.com/blog/round-anything-a-pragmatic-approach-to-openscad-design/).
[Full documentation of the API is here](https://kurthutten.com/blog/round-anything-api/).

View File

@@ -29,6 +29,11 @@ let(
points[listWrap(i+1,lp)],
],thick=offset,mode=isCWorCCW)];
function reverseList(list) = [ for(i=[len(list) - 1:-1:0]) list[i] ];
// Apply `reverseList` to the array of vertex indices for an array of faces
function invertFaces(faces) = [ for(f=faces) reverseList(f) ];
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
@@ -129,7 +134,7 @@ function extrudePolygonWithRadius(radiiPoints,h=5,r1=1,r2=1,fn=4)=
let(
// top is the top curved part of the extrude
top=makeCurvedPartOfPolyHedron(radiiPoints,r1,fn),
topRadiusPoints=translate3Dcoords(top[0],[0,0,h-r1]),
topRadiusPoints=translate3Dcoords(top[0],[0,0,h-abs(r1)]),
singeLayerLength=top[2],
topRadiusFaces=top[1],
radiusPointsLength=len(topRadiusPoints), // is the same length as bottomRadiusPoints
@@ -152,7 +157,7 @@ let(
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])
finalPolyhedronFaces=concat(topRadiusFaces,invertFaces(bottomRadiusFaces),invertFaces(sideFaces),[topCapFace],invertFaces([bottomCapFace]))
)
[
finalPolyhedronPoints,
@@ -160,7 +165,11 @@ let(
];
module polyRoundExtrude(radiiPoints,length=5,r1=1,r2=1,fn=10,convexity=10) {
polyhedronPointsNFaces=extrudePolygonWithRadius(radiiPoints,length,r1,r2,fn);
orderedRadiiPoints = CWorCCW(radiiPoints) == 1
? reverseList(radiiPoints)
: radiiPoints;
polyhedronPointsNFaces=extrudePolygonWithRadius(orderedRadiiPoints,length,r1,r2,fn);
polyhedron(points=polyhedronPointsNFaces[0], faces=polyhedronPointsNFaces[1], convexity=convexity);
}
@@ -327,14 +336,22 @@ function parallelFollow(rp,thick=4,minR=1,mode=1)=
)
concat(cen,outR);
function is90or270(ang)=ang==90?1:ang==270?1:0;
function findPoint(ang1,refpoint1,ang2,refpoint2,r=0)=
// finds the intersection of two lines given two angles and points on those lines
let(
overrideX=is90or270(ang1)?
refpoint1.x:
is90or270(ang2)?
refpoint2.x:
0,
m1=tan(ang1),
c1=refpoint1.y-m1*refpoint1.x,
m2=tan(ang2),
c2=refpoint2.y-m2*refpoint2.x,
outputX=(c2-c1)/(m1-m2),
outputY=m1*outputX+c1
outputX=overrideX?overrideX:(c2-c1)/(m1-m2),
outputY=is90or270(ang1)?m2*outputX+c2:m1*outputX+c1
)
[outputX,outputY,r];
@@ -374,13 +391,23 @@ function beamChain(radiiPoints,offset1=0,offset2,mode=0,minR=0,startAngle,endAng
getAngle(radiiPoints[Lrp-1],radiiPoints[Lrp-2])+endAngle:
endAngle,
OffLn1=[for(i=[0:Lrp3]) offset1==0?radiiPoints[i+1]:parallelFollow([radiiPoints[i],radiiPoints[i+1],radiiPoints[i+2]],offset1,minR,mode=CWorCCW1)],
OffLn2=[for(i=[0:Lrp3]) offset2==0?radiiPoints[i+1]:parallelFollow([radiiPoints[i],radiiPoints[i+1],radiiPoints[i+2]],offset2b,minR,mode=CWorCCW2)],
OffLn2=[for(i=[0:Lrp3]) offset2==0?radiiPoints[i+1]:parallelFollow([radiiPoints[i],radiiPoints[i+1],radiiPoints[i+2]],offset2b,minR,mode=CWorCCW2)],
Rp1=abs(radiiPoints[0].z),
Rp2=abs(radiiPoints[Lrp-1].z),
endP1a=findPoint(getAngle(radiiPoints[0],radiiPoints[1]), OffLn1[0], startAngle,radiiPoints[0], Rp1),
endP1b=findPoint(getAngle(radiiPoints[Lrp-1],radiiPoints[Lrp-2]), OffLn1[len(OffLn1)-1], endAngle,radiiPoints[Lrp-1], Rp2),
endP2a=findPoint(getAngle(radiiPoints[0],radiiPoints[1]), OffLn2[0], startAngle,radiiPoints[0], Rp1),
endP2b=findPoint(getAngle(radiiPoints[Lrp-1],radiiPoints[Lrp-2]), OffLn2[len(OffLn1)-1], endAngle,radiiPoints[Lrp-1], Rp2),
endP1aAngle = getAngle(radiiPoints[0],radiiPoints[1]),
endP1a=findPoint(endP1aAngle, OffLn1[0], startAngle,radiiPoints[0], Rp1),
endP1bAngle = getAngle(radiiPoints[Lrp-1],radiiPoints[Lrp-2]),
endP1b=findPoint(endP1bAngle, OffLn1[len(OffLn1)-1], endAngle,radiiPoints[Lrp-1], Rp2),
endP2aAngle = getAngle(radiiPoints[0],radiiPoints[1]),
endP2a=findPoint(endP2aAngle, OffLn2[0], startAngle,radiiPoints[0], Rp1),
endP2bAngle = getAngle(radiiPoints[Lrp-1],radiiPoints[Lrp-2]),
endP2b=findPoint(endP2bAngle, OffLn2[len(OffLn1)-1], endAngle,radiiPoints[Lrp-1], Rp2),
absEnda=getAngle(endP1a,endP2a),
absEndb=getAngle(endP1b,endP2b),
negRP1a=[cos(absEnda)*radiiPoints[0].z*10+endP1a.x, sin(absEnda)*radiiPoints[0].z*10+endP1a.y, 0.0],
@@ -432,22 +459,23 @@ function CentreN2PointsArc(p1,p2,cen,mode=0,fn)=
mode==3, plotted counter clockwise
*/
let(
CWorCCW=CWorCCW([cen,p1,p2]),//determine the direction of rotation
isCWorCCW=CWorCCW([cen,p1,p2]),//determine the direction of rotation
//determine the arc angle depending on the mode
p1p2Angle=cosineRuleAngle(p2,cen,p1),
arcAngle=
mode==0?p1p2Angle:
mode==1?p1p2Angle-360:
mode==2&&CWorCCW==-1?p1p2Angle:
mode==2&&CWorCCW== 1?p1p2Angle-360:
mode==3&&CWorCCW== 1?p1p2Angle:
mode==3&&CWorCCW==-1?p1p2Angle-360:
cosineRuleAngle(p2,cen,p1)
,
mode==2&&isCWorCCW==-1?p1p2Angle:
mode==2&&isCWorCCW== 1?p1p2Angle-360:
mode==3&&isCWorCCW== 1?p1p2Angle:
mode==3&&isCWorCCW==-1?p1p2Angle-360:
cosineRuleAngle(p2,cen,p1),
r=pointDist(p1,cen),//determine the radius
p1Angle=getAngle(cen,p1) //angle of line 1
)
[for(i=[0:fn]) [cos(p1Angle+(arcAngle/fn)*i*CWorCCW)*r+cen[0],sin(p1Angle+(arcAngle/fn)*i*CWorCCW)*r+cen[1]]];
[for(i=[0:fn])
let(angleIncrement=(arcAngle/fn)*i*isCWorCCW)
[cos(p1Angle+angleIncrement)*r+cen.x,sin(p1Angle+angleIncrement)*r+cen.y]];
function translateRadiiPoints(radiiPoints,tran=[0,0],rot=0)=
[for(i=radiiPoints)
@@ -539,7 +567,7 @@ function mirrorPoints(radiiPoints,rot=0,endAttenuation=[0,0])= //mirrors a list
concat(radiiPoints,temp2);
function processRadiiPoints(rp)=
[for(i=[0:len(rp)-1])
[for(i=[0:len(rp)-1])
processRadiiPoints2(rp,i)
];
@@ -663,9 +691,9 @@ function getAngle(p1,p2)=p1==p2?0:invtan(p2[0]-p1[0],p2[1]-p1[1]);
function getMidpoint(p1,p2)=[(p1[0]+p2[0])/2,(p1[1]+p2[1])/2]; //returns the midpoint of two points
function pointDist(p1,p2)=sqrt(abs(sq(p1[0]-p2[0])+sq(p1[1]-p2[1]))); //returns the distance between two points
function isColinear(p1,p2,p3)=getGradient(p1,p2)==getGradient(p2,p3)?1:0;//return 1 if 3 points are colinear
module polyline(p) {
module polyline(p, width=0.3) {
for(i=[0:max(0,len(p)-1)]){
line(p[i],p[listWrap(i+1,len(p) )]);
color([i*1/len(p),1-i*1/len(p),0,0.5])line(p[i],p[listWrap(i+1,len(p) )],width);
}
} // polyline plotter
module line(p1, p2 ,width=0.3) { // single line plotter

View File

@@ -1,6 +1,7 @@
include <polyround.scad>
basicPolyRoundExample();
// polyLineExample();
// parametricPolyRoundExample();
// experimentalParametricPolyRoundExample();
// conflicResolutionExample();
@@ -9,15 +10,27 @@ basicPolyRoundExample();
// beamChainExample();
// mirrorPointsExample();
// radiusExtrudeExample();
// radiusExtrudePolygon();
// polyRoundExtrudeExample();
// testing
// testGeometries();
module basicPolyRoundExample(){
// polyLine is a dev helper. Aim is to show the points of the polygon and their order before
// you're ready to move on to polyRound and a polygon
radiiPoints=[[-4,0,1],[5,3,1.5],[0,7,0.1],[8,7,10],[20,20,0.8],[10,0,10]];
polygon(polyRound(radiiPoints,30));
%translate([0,0,0.3])polygon(getpoints(radiiPoints));//transparent copy of the polgon without rounding
}
module polyLineExample() {
radiiPoints=[[-4,0,1],[5,3,1.5],[0,7,0.1],[8,7,10],[20,20,0.8],[10,0,10]];
polyline(polyRound(radiiPoints,3), 0.05);
translate([0,10,0])
polyline(radiiPoints, 0.05);
}
module parametricPolyRoundExample() {
//Example of how a parametric part might be designed with this tool
width=20; height=25;
@@ -67,7 +80,7 @@ module experimentalParametricPolyRoundExample() {
module conflicResolutionExample(){
//example of radii conflict handling and debuging feature
function makeRadiiPoints(r1, r2)=[[0,0,0],[0,20,r1],[20,20,r1],[20,0,0]];
function makeRadiiPoints(r1, r2)=[[0,0,0],[0,20,r1],[20,20,r2],[20,0,0]];
// the squre shape being 20 wide, two radii of 10 both fit into the shape (just)
translate([-25,0,0])polygon(polyRound(makeRadiiPoints(10,10),50));
@@ -79,7 +92,7 @@ module conflicResolutionExample(){
translate([25,0,0])polygon(polyRound(makeRadiiPoints(10,40),50));
//mode 2 = no radii limiting
translate([50,0,0])polygon(polyRound(makeRadiiPoints(15,20),50,mode=2));
translate([50,0,0])polygon(polyRound(makeRadiiPoints(12,20),50,mode=2));
}
module translateRadiiPointsExample() {
@@ -113,8 +126,8 @@ module translateRadiiPointsExample() {
module 2dShellExample(){
radiiPoints=[[-4,0,1],[5,3,1.5],[0,7,0.1],[8,7,10],[20,20,0.8],[10,0,10]];
shell2d(-0.5)polygon(polyRound(radiiPoints,30));
translate([0,-10,0])shell2d(-0.5){
linear_extrude(1)shell2d(-0.5)polygon(polyRound(radiiPoints,30));
translate([0,-10,0])linear_extrude(1)shell2d(-0.5){
polygon(polyRound(radiiPoints,30));
translate([8,8])gridpattern(memberW = 0.3, sqW = 1, iter = 17, r = 0.2);
}
@@ -124,43 +137,43 @@ module beamChainExample(){
function beamPoints(r1,r2,rStart=0,rEnd=0)=[[0,0,rStart],[2,8,0],[5,4,r1],[15,10,r2],[17,2,rEnd]];
// chained lines by themselves
translate(){
translate([0,0,0]){
radiiPoints=beamPoints(0,0);
for(i=[0: len(radiiPoints)]){color("red")translate([radiiPoints[i].x,radiiPoints[i].y,0])cylinder(d=0.2, h=1);}
polygon(polyRound(beamChain(radiiPoints,offset1=0.02, offset2=-0.02),20));
for(i=[0: len(radiiPoints)-1]){color("red")translate([radiiPoints[i].x,radiiPoints[i].y,0])cylinder(d=0.2, h=1);}
linear_extrude(1)polygon(polyRound(beamChain(radiiPoints,offset1=0.02, offset2=-0.02),20));
}
// Add some radii to the line transitions
translate([0,-7,0]){
radiiPoints=beamPoints(2,1);
for(i=[0: len(ex3)]){color("red")translate([radiiPoints[i].x,radiiPoints[i].y,0])cylinder(d=0.2, h=1);}
polygon(polyRound(beamChain(radiiPoints,offset1=0.02, offset2=-0.02),20));
for(i=[0: len(radiiPoints)-1]){color("red")translate([radiiPoints[i].x,radiiPoints[i].y,0])cylinder(d=0.2, h=1);}
linear_extrude(1)polygon(polyRound(beamChain(radiiPoints,offset1=0.02, offset2=-0.02),20));
}
// Give make the lines beams with some thickness
translate([0,-7*2,0]){
radiiPoints=beamPoints(2,1);
polygon(polyRound(beamChain(radiiPoints,offset1=0.5, offset2=-0.5),20));
linear_extrude(1)polygon(polyRound(beamChain(radiiPoints,offset1=0.5, offset2=-0.5),20));
}
// Add an angle to the start of the beam
translate([0,-7*3,0]){
radiiPoints=beamPoints(2,1);
polygon(polyRound(beamChain(radiiPoints,offset1=0.5, offset2=-0.5, startAngle=45),20));
linear_extrude(1)polygon(polyRound(beamChain(radiiPoints,offset1=0.5, offset2=-0.5, startAngle=45),20));
}
// Put a negative radius at the start for transationing to a flat surface
translate([0,-7*4,0]){
radiiPoints=beamPoints(2,1,rStart=-0.7);
polygon(polyRound(beamChain(radiiPoints,offset1=0.5, offset2=-0.5, startAngle=45),20));
linear_extrude(1)polygon(polyRound(beamChain(radiiPoints,offset1=0.5, offset2=-0.5, startAngle=45),20));
}
// Define more points for a polygon to be atteched to the end of the beam chain
clipP=[[16,1.2,0],[16,0,0],[16.5,0,0],[16.5,1,0.2],[17.5,1,0.2],[17.5,0,0],[18,0,0],[18,1.2,0]];
translate([-15,-7*5+3,0]){
for(i=[0:len(clipP)-1]){color("red")translate([clipP[i].x,clipP[i].y,0])cylinder(d=0.2, h=1);}
polygon(polyRound(clipP,20));
linear_extrude(1)polygon(polyRound(clipP,20));
}
// Attached to the end of the beam chain by dividing the beam paths in forward and return and
@@ -170,7 +183,7 @@ module beamChainExample(){
forwardPath=beamChain(radiiPoints,offset1=0.5,startAngle=-15,mode=2);
returnPath=revList(beamChain(radiiPoints,offset1=-0.5,startAngle=-15,mode=2));
entirePath=concat(forwardPath,clipP,returnPath);
polygon(polyRound(entirePath,20));
linear_extrude(1)polygon(polyRound(entirePath,20));
}
// Add transitioning radii into the end polygong
@@ -179,12 +192,13 @@ module beamChainExample(){
forwardPath=beamChain(radiiPoints,offset1=0.5,startAngle=-15,mode=2);
returnPath=revList(beamChain(radiiPoints,offset1=-0.5,startAngle=-15,mode=2));
entirePath=concat(forwardPath,clipP,returnPath);
polygon(polyRound(entirePath,20));
linear_extrude(1)polygon(polyRound(entirePath,20));
}
// Define multiple shells from the the one set of points
translate([0,-7*9,0]){
for(i=[0:2]){polygon(polyRound(beamChain(ex3,offset1=-1+i*0.4, offset2=-1+i*0.4+0.25),20));}
radiiPoints=beamPoints(2,1,rEnd=3);
for(i=[0:2]){linear_extrude(1)polygon(polyRound(beamChain(radiiPoints,offset1=-1+i*0.4, offset2=-1+i*0.4+0.25),20));}
}
}
@@ -215,3 +229,41 @@ module gridpattern(memberW = 4, sqW = 12, iter = 5, r = 3){
}
}
}
module testGeometries() {
// Check these shapes preview (plus "thrown together") and render correctly with each PR
points = [
[0, 10, 5],
[10, 0, 5],
[0, -10, 5],
[-10, 0, 5],
];
reversedPoints = [
[-10, 0, 5],
[0, -10, 5],
[10, 0, 5],
[0, 10, 5],
];
polyRoundExtrudeTestShape(points);
translate([0,20,0])polyRoundExtrudeTestShape(reversedPoints);
// Bug report submitted by @lopisan in issue #16, similar to #11, geometry breaks with 90 degree angles
didBreakWhen0=0;
issue16pointsa=[[0, 0, 0], [0+didBreakWhen0, 10, 0], [10, 10+didBreakWhen0, 0]];
translate([20,0,0])linear_extrude(1)polygon(polyRound( beamChain(issue16pointsa, offset1=1, offset2=-1), 30));
didBreakWhen0b=1e-6;
issue16pointsb=[[0, 0, 0], [0+didBreakWhen0b, 10, 0], [10, 10+didBreakWhen0b, 0]];
translate([20,15,0])linear_extrude(1)polygon(polyRound( beamChain(issue16pointsb, offset1=1, offset2=-1), 30));
}
module polyRoundExtrudeTestShape(points) {
// make sure no faces are inverted
difference() {
translate([0, 0, -2.5]) polyRoundExtrude(points,r1=-1,r2=1);
sphere(d=9);
translate([0,0,7])sphere(d=9);
}
}