1+ /*
2+ * OpenSCAD 2D Shapes Library (www.openscad.org)
3+ * Copyright (C) 2012 Peter Uithoven
4+ *
5+ * License: LGPL 2.1 or later
6+ */
7+
8+ // 2D Shapes
9+ // ngon(sides, radius, center=false);
10+ // complexRoundSquare(size,rads1=[0,0], rads2=[0,0], rads3=[0,0], rads4=[0,0], center=true)
11+ // roundedSquare(pos=[10,10],r=2)
12+ // ellipsePart(width,height,numQuarters)
13+ // donutSlice(innerSize,outerSize, start_angle, end_angle)
14+ // pieSlice(size, start_angle, end_angle) //size in radius(es)
15+ // ellipse(width, height) {
16+
17+ // Examples
18+ /* use <layouts.scad>;
19+ grid(105,105,true,4)
20+ {
21+ // ellipse
22+ ellipse(50,75);
23+
24+ // part of ellipse (a number of quarters)
25+ ellipsePart(50,75,3);
26+ ellipsePart(50,75,2);
27+ ellipsePart(50,75,1);
28+
29+ // complexRoundSquare examples
30+ complexRoundSquare([75,100],[20,10],[20,10],[20,10],[20,10]);
31+ complexRoundSquare([75,100],[0,0],[0,0],[30,50],[20,10]);
32+ complexRoundSquare([50,50],[10,20],[10,20],[10,20],[10,20],false);
33+ complexRoundSquare([100,100]);
34+ complexRoundSquare([100,100],rads1=[20,20],rads3=[20,20]);
35+
36+ // pie slice
37+ pieSlice(50,0,10);
38+ pieSlice(50,45,190);
39+ pieSlice([50,20],180,270);
40+
41+ // donut slice
42+ donutSlice(20,50,0,350);
43+ donutSlice(30,50,190,270);
44+ donutSlice([40,22],[50,30],180,270);
45+ donutSlice([50,20],50,180,270);
46+ donutSlice([20,30],[50,40],0,270);
47+ }*/
48+ // ----------------------
49+
50+ // size, top left radius, top right radius, bottom right radius, bottom left radius, center
51+ module complexRoundSquare(size,rads1=[0,0], rads2=[0,0], rads3=[0,0], rads4=[0,0], center=true)
52+ {
53+ width = size[0 ];
54+ height = size[1 ];
55+ // %square(size=[width, height],center=true);
56+ x1 = 0 - width/2 + rads1[0 ];
57+ y1 = 0 - height/2 + rads1[1 ];
58+ x2 = width/2 - rads2[0 ];
59+ y2 = 0 - height/2 + rads2[1 ];
60+ x3 = width/2 - rads3[0 ];
61+ y3 = height/2 - rads3[1 ];
62+ x4 = 0 - width/2 + rads4[0 ];
63+ y4 = height/2 - rads4[1 ];
64+
65+ scs = 0.1 ; // straight corner size
66+
67+ x = (center)? 0 : width/2 ;
68+ y = (center)? 0 : height/2 ;
69+
70+ translate ([x,y,0 ])
71+ {
72+ hull () {
73+ // top left
74+ if (rads1[0 ] > 0 && rads1[1 ] > 0 )
75+ translate ([x1,y1]) mirror ([1 ,0 ]) ellipsePart(rads1[0 ]* 2 ,rads1[1 ]* 2 ,1 );
76+ else
77+ translate ([x1,y1]) square(size= [scs, scs]);
78+
79+ // top right
80+ if (rads2[0 ] > 0 && rads2[1 ] > 0 )
81+ translate ([x2,y2]) ellipsePart(rads2[0 ]* 2 ,rads2[1 ]* 2 ,1 );
82+ else
83+ translate ([width/2 - scs,0 - height/2 ]) square(size= [scs, scs]);
84+
85+ // bottom right
86+ if (rads3[0 ] > 0 && rads3[1 ] > 0 )
87+ translate ([x3,y3]) mirror ([0 ,1 ]) ellipsePart(rads3[0 ]* 2 ,rads3[1 ]* 2 ,1 );
88+ else
89+ translate ([width/2 - scs,height/2 - scs]) square(size= [scs, scs]);
90+
91+ // bottom left
92+ if (rads4[0 ] > 0 && rads4[1 ] > 0 )
93+ translate ([x4,y4]) rotate ([0 ,0 ,- 180 ]) ellipsePart(rads4[0 ]* 2 ,rads4[1 ]* 2 ,1 );
94+ else
95+ #translate ([x4,height/2 - scs]) square(size= [scs, scs]);
96+ }
97+ }
98+ }
99+ module roundedSquare(pos=[10,10],r=2) {
100+ minkowski () {
101+ square([pos[0 ]- r* 2 ,pos[1 ]- r* 2 ],center= true );
102+ circle(r= r);
103+ }
104+ }
105+ // round shapes
106+ // The orientation might change with the implementation of circle...
107+ module ngon(sides, radius, center=false){
108+ rotate ([0 , 0 , 360 /sides/2 ]) circle(r= radius, $ fn= sides, center= center);
109+ }
110+ module ellipsePart(width,height,numQuarters)
111+ {
112+ o = 1 ; // slight overlap to fix a bug
113+ difference ()
114+ {
115+ ellipse(width,height);
116+ if (numQuarters <= 3 )
117+ translate ([0 - width/2 - o,0 - height/2 - o,0 ]) square([width/2 + o,height/2 + o]);
118+ if (numQuarters <= 2 )
119+ translate ([0 - width/2 - o,- o,0 ]) square([width/2 + o,height/2 + o* 2 ]);
120+ if (numQuarters < 2 )
121+ translate ([- o,0 ,0 ]) square([width/2 + o* 2 ,height/2 + o]);
122+ }
123+ }
124+ module donutSlice(innerSize,outerSize, start_angle, end_angle)
125+ {
126+ difference ()
127+ {
128+ pieSlice(outerSize, start_angle, end_angle);
129+ if (len(innerSize) > 1 ) ellipse(innerSize[0 ]* 2 ,innerSize[1 ]* 2 );
130+ else circle(innerSize);
131+ }
132+ }
133+ module pieSlice(size, start_angle, end_angle) //size in radius(es)
134+ {
135+ rx = ((len(size) > 1 )? size[0 ] : size);
136+ ry = ((len(size) > 1 )? size[1 ] : size);
137+ trx = rx* sqrt (2 ) + 1 ;
138+ try = ry* sqrt (2 ) + 1 ;
139+ a0 = (4 * start_angle + 0 * end_angle) / 4 ;
140+ a1 = (3 * start_angle + 1 * end_angle) / 4 ;
141+ a2 = (2 * start_angle + 2 * end_angle) / 4 ;
142+ a3 = (1 * start_angle + 3 * end_angle) / 4 ;
143+ a4 = (0 * start_angle + 4 * end_angle) / 4 ;
144+ if (end_angle > start_angle)
145+ intersection () {
146+ if (len(size) > 1 )
147+ ellipse(rx* 2 ,ry* 2 );
148+ else
149+ circle(rx);
150+ polygon([
151+ [0 ,0 ],
152+ [trx * cos (a0), try * sin (a0)],
153+ [trx * cos (a1), try * sin (a1)],
154+ [trx * cos (a2), try * sin (a2)],
155+ [trx * cos (a3), try * sin (a3)],
156+ [trx * cos (a4), try * sin (a4)],
157+ [0 ,0 ]
158+ ]);
159+ }
160+ }
161+ module ellipse(width, height) {
162+ scale ([1 , height/width, 1 ]) circle(r= width/2 );
163+ }
0 commit comments