1+ // An example of simulating a simple rope. For, the construction of rope, catenary algorithm(https://en.wikipedia.org/wiki/Catenary) is used.
2+ // The catenary is a curve that describes the shape of a hanging chain or cable, or the curve described by a freely hanging chain or cable.
3+ // The implementation of catenary algorithm is based on the following js implementation : https://github.com/dulnan/catenary-curve/blob/9cb7e53e2db4bd5c499f5051abde8bfd853d946a/src/main.ts#L254
4+ // Catenary dart algorithm gist : https://gist.github.com/rutvik110/56f4626c95b92b8cf2c95283d4682331
5+
16import 'dart:developer' as dev;
27import 'dart:math' as math;
38
@@ -28,9 +33,9 @@ class _RopesViewState extends State<RopesView> {
2833
2934 late double delta;
3035
31- final answer1Key = GlobalKey ();
32- final answer2Key = GlobalKey ();
33- final answer3Key = GlobalKey ();
36+ final station1Key = GlobalKey ();
37+ final station2Key = GlobalKey ();
38+ final station3Key = GlobalKey ();
3439 bool isConnected = false ;
3540 bool isConnected2 = false ;
3641 bool isConnected3 = false ;
@@ -84,6 +89,7 @@ class _RopesViewState extends State<RopesView> {
8489 backgroundColor: Colors .black,
8590 body: Stack (
8691 children: [
92+ // DragPoint 1
8793 Positioned (
8894 top: dragPoint.dy - 48 / 1.2 ,
8995 left: dragPoint.dx - 48 / 2 ,
@@ -92,7 +98,7 @@ class _RopesViewState extends State<RopesView> {
9298 child: Draggable (
9399 onDragUpdate: ((details) {
94100 dragPoint = details.localPosition;
95- isConnected = isConnectedPowere (answer1Key , dragPoint);
101+ isConnected = isConnectedPowere (station1Key , dragPoint);
96102 setState (() {});
97103 }),
98104 feedback: const SizedBox .shrink (),
@@ -103,6 +109,7 @@ class _RopesViewState extends State<RopesView> {
103109 )),
104110 ),
105111 ),
112+ // DragPoint 2
106113 Positioned (
107114 top: dragPoint2.dy - 48 / 1.2 ,
108115 left: dragPoint2.dx - 48 / 2 ,
@@ -111,7 +118,7 @@ class _RopesViewState extends State<RopesView> {
111118 child: Draggable (
112119 onDragUpdate: ((details) {
113120 dragPoint2 = details.localPosition;
114- isConnected2 = isConnectedPowere (answer2Key , dragPoint2);
121+ isConnected2 = isConnectedPowere (station2Key , dragPoint2);
115122 setState (() {});
116123 }),
117124 feedback: const SizedBox .shrink (),
@@ -123,6 +130,7 @@ class _RopesViewState extends State<RopesView> {
123130 ),
124131 ),
125132 ),
133+ // DragPoint 3
126134 Positioned (
127135 top: dragPoint3.dy - 48 / 1.2 ,
128136 left: dragPoint3.dx - 48 / 2 ,
@@ -131,7 +139,7 @@ class _RopesViewState extends State<RopesView> {
131139 child: Draggable (
132140 onDragUpdate: ((details) {
133141 dragPoint3 = details.localPosition;
134- isConnected3 = isConnectedPowere (answer3Key , dragPoint3);
142+ isConnected3 = isConnectedPowere (station3Key , dragPoint3);
135143 dev.log (isConnected3.toString ());
136144 setState (() {});
137145 }),
@@ -144,6 +152,7 @@ class _RopesViewState extends State<RopesView> {
144152 ),
145153 ),
146154 ),
155+ // Cars
147156 IgnorePointer (
148157 ignoring: true ,
149158 child: FutureBuilder <Stripes >(
@@ -171,7 +180,6 @@ class _RopesViewState extends State<RopesView> {
171180 ? Colors .amber.toColorVector ()
172181 : Colors .blueGrey.toColorVector (),
173182 ),
174- delta,
175183 ),
176184 size: Size .infinite,
177185 ),
@@ -194,7 +202,6 @@ class _RopesViewState extends State<RopesView> {
194202 ? Colors .green.toColorVector ()
195203 : Colors .blueGrey.toColorVector (),
196204 ),
197- delta,
198205 ),
199206 size: Size .infinite,
200207 ),
@@ -217,7 +224,6 @@ class _RopesViewState extends State<RopesView> {
217224 ? Colors .red.toColorVector ()
218225 : Colors .blueGrey.toColorVector (),
219226 ),
220- delta,
221227 ),
222228 size: Size .infinite,
223229 ),
@@ -228,6 +234,7 @@ class _RopesViewState extends State<RopesView> {
228234 },
229235 ),
230236 ),
237+ // Changing Stations
231238 IgnorePointer (
232239 ignoring: true ,
233240 child: Padding (
@@ -289,7 +296,7 @@ class _RopesViewState extends State<RopesView> {
289296 Container (
290297 height: 100 ,
291298 width: 100 ,
292- key: answer1Key ,
299+ key: station1Key ,
293300 decoration: BoxDecoration (
294301 color: const Color .fromARGB (255 , 40 , 40 , 40 ),
295302 borderRadius: BorderRadius .circular (10.0 ),
@@ -306,7 +313,7 @@ class _RopesViewState extends State<RopesView> {
306313 Container (
307314 height: 100 ,
308315 width: 100 ,
309- key: answer2Key ,
316+ key: station2Key ,
310317 decoration: BoxDecoration (
311318 color: const Color .fromARGB (255 , 40 , 40 , 40 ),
312319 borderRadius: BorderRadius .circular (10.0 ),
@@ -324,7 +331,7 @@ class _RopesViewState extends State<RopesView> {
324331 Container (
325332 height: 100 ,
326333 width: 100 ,
327- key: answer3Key ,
334+ key: station3Key ,
328335 decoration: BoxDecoration (
329336 color: const Color .fromARGB (255 , 40 , 40 , 40 ),
330337 borderRadius: BorderRadius .circular (10.0 ),
@@ -352,13 +359,12 @@ class RopesPainter extends CustomPainter {
352359 this .startPoint,
353360 this .endPoint,
354361 this .stripes,
355- this .delta,
356362 );
357363
358364 final Offset endPoint;
359365 final Offset startPoint;
360366 final Shader stripes;
361- final double delta;
367+
362368 @override
363369 void paint (Canvas canvas, Size size) {
364370 // TODO: implement paint
@@ -374,8 +380,7 @@ class RopesPainter extends CustomPainter {
374380 math.Point (startPoint.dx / size.width, startPoint.dy / size.height);
375381 final finalendPoint =
376382 math.Point (endPoint.dx / size.width, endPoint.dy / size.height);
377- final radius = math.sqrt (math.pow (endPoint.dx - startPoint.dx, 2.0 ) +
378- math.pow (endPoint.dy - startPoint.dy, 2.0 ));
383+
379384 final curvePoints = getCaternaryCurve (startingPoint, finalendPoint, 1 );
380385 final points = curvePoints
381386 .map ((e) => Offset (e.x * size.width, (e.y) * size.height))
@@ -406,10 +411,10 @@ class RopesPainter extends CustomPainter {
406411
407412 final a = - getCatenaryParameter (h.toDouble (), v.toDouble (), chainLength,
408413 iterationLimit, point1, point2);
409-
410- // if (a.isNaN) {
411- // return [point1, point2];
412- // }
414+ // Handle NAN/rope being stretched than its original length case
415+ if (a.isNaN) {
416+ return [point1, point2];
417+ }
413418 final x = (a * math.log ((chainLength + v) / (chainLength - v)) - h) * 0.5 ;
414419 final y = a * cosh (x / a);
415420
0 commit comments