@@ -6,21 +6,142 @@ class Curvature {
66 this . key = "curvature" ;
77 this . name = "Curvature" ;
88 this . env = env ;
9- this . config = { } ;
9+
10+ this . config = {
11+ "radius" : {
12+ "name" : "Start Radius" ,
13+ "value" : null ,
14+ "input" : {
15+ "type" : "createSlider" ,
16+ "params" : [
17+ 0 ,
18+ 1 ,
19+ 0.05 ,
20+ 0.01
21+ ] ,
22+ "class" : "slider" ,
23+ "displayValue" : true
24+ }
25+ } ,
26+ "iterations" : {
27+ "name" : "Iterations" ,
28+ "value" : null ,
29+ "input" : {
30+ "type" : "createSlider" ,
31+ "params" : [
32+ 2 ,
33+ 100 ,
34+ 40 ,
35+ 2
36+ ] ,
37+ "class" : "slider" ,
38+ "displayValue" : true
39+ }
40+ } ,
41+ } ;
42+
1043 this . path = [ ] ;
1144 }
1245
1346 draw ( ) {
1447
1548 const PathHelp = new PathHelper ( ) ;
1649
50+ // Update object
51+ this . config . radius . value = parseFloat ( document . querySelector ( '#pattern-controls > div:nth-child(1) > input' ) . value ) ;
52+ this . config . iterations . value = parseInt ( document . querySelector ( '#pattern-controls > div:nth-child(2) > input' ) . value ) ;
53+
54+ // Display selected values
55+ document . querySelector ( '#pattern-controls > div.pattern-control:nth-child(1) > span' ) . innerHTML = this . config . radius . value ;
56+ document . querySelector ( '#pattern-controls > div.pattern-control:nth-child(2) > span' ) . innerHTML = this . config . iterations . value ;
57+
58+ let path = [ ] ;
59+
60+ // Set maximum radius based on table size
1761 const max_r = 0.5 * Math . min (
1862 ( this . env . table . x . max - this . env . table . x . min ) ,
1963 ( this . env . table . y . max - this . env . table . y . min )
2064 ) ;
2165
22- // Create a circle
23- let path = PathHelp . polygon ( 60 , 0.5 * max_r ) ;
66+ // Crop Circle
67+ const cropShape = PathHelp . polygon ( 60 , max_r ) ;
68+
69+ // This needs to be even to mirror properly
70+ const i_max = this . config . iterations . value ;
71+
72+ // const starting_radius = this.config.radius.value * max_r;
73+ const starting_radius = this . config . radius . value * max_r ;
74+ const ending_radius = 40.0 * max_r ;
75+ for ( let i = 0 ; i < i_max ; i ++ ) {
76+
77+ // The radius should increase. It can be eased using different methods
78+ const radius = starting_radius + this . #easeInQuart( i / i_max ) * ( ending_radius - starting_radius ) ;
79+
80+ // The y position should start out near the top and the bottom of the circle/arc
81+ // should step down by one increment of (i) as a fraction of the maximum radius,
82+ // ensuring equal spacing between each arc
83+ const y = max_r + 1.0 * radius - ( max_r * ( i / i_max ) ) ;
84+
85+ const sides = Math . round ( ( 2 * Math . PI * radius ) / ( 0.5 * this . env . ball . diameter ) ) ;
86+ let arc = PathHelp . arc (
87+ [ 0 , 0 ] ,
88+ radius ,
89+ 2 * Math . PI ,
90+ 0.5 * Math . PI ,
91+ sides
92+ ) ;
93+
94+ if ( i % 2 ) {
95+ arc . reverse ( ) ;
96+ }
97+
98+ arc = PathHelp . translatePath ( arc , [ 0 , y ] ) ;
99+
100+ let cropped = PathHelp . cropToShape ( [ arc ] , cropShape ) ;
101+
102+ if ( cropped . length ) {
103+ path = path . concat ( cropped [ 0 ] ) ;
104+ }
105+ }
106+
107+ const horizontal_line = [
108+ [ - max_r , 0 ] ,
109+ [ 0 , 0 ]
110+ ] ;
111+ if ( path [ path . length - 1 ] [ 0 ] > 0 ) {
112+ horizontal_line . reverse ( ) ;
113+ }
114+ path = path . concat ( horizontal_line ) ;
115+
116+ // Duplicate and flip
117+ let flip = PathHelp . deepCopy ( path ) ;
118+ flip . reverse ( ) ;
119+ flip = PathHelp . rotatePath ( flip , Math . PI ) ;
120+ flip . shift ( ) ;
121+ path = path . concat ( flip ) ;
122+
123+ // Define arc from home position to start of path
124+ const arc_from_home = PathHelp . arc (
125+ [ 0 , 0 ] ,
126+ max_r ,
127+ 0.5 * Math . PI ,
128+ 0 ,
129+ 12
130+ ) ;
131+
132+ // Define arc from end of path to home position
133+ const arc_to_home = PathHelp . arc (
134+ [ 0 , 0 ] ,
135+ max_r ,
136+ 0.5 * Math . PI ,
137+ 1.5 * Math . PI ,
138+ 12
139+ ) ;
140+
141+ // Redefine path with start/ending paths
142+ path = arc_from_home . concat ( path , arc_to_home ) ;
143+
144+ // path = PathHelp.simplify(path, 0.5 * this.env.ball.diameter);
24145
25146 // Simplify decimal precision
26147 path = path . map ( function ( point ) {
@@ -31,6 +152,30 @@ class Curvature {
31152
32153 return path ;
33154 }
155+
156+ #easeOutCubic( x ) {
157+ return 1 - Math . pow ( 1 - x , 3 ) ;
158+ }
159+
160+ #easeInQuart( x ) {
161+ return x * x * x * x ;
162+ }
163+
164+ #easeInCubic( x ) {
165+ return x * x * x ;
166+ }
167+
168+ #easeInQuad( x ) {
169+ return x * x ;
170+ }
171+
172+ #easeInCirc( x ) {
173+ return 1 - Math . sqrt ( 1 - Math . pow ( x , 2 ) ) ;
174+ }
175+
176+ #easeInExpo( x ) {
177+ return x === 0 ? 0 : Math . pow ( 2 , 10 * x - 10 ) ;
178+ }
34179}
35180
36181export default Curvature ;
0 commit comments