summaryrefslogtreecommitdiff
path: root/Homework/cs4700/dart/fractal.dart
blob: c0753253ff8cd3d4d4f0d3d82588a333ef94cf8e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
import 'package:flutter/material.dart';
import 'dart:math' as math;

/// Your code should go into the DrawFractal class.

/// The fractal is drawn as an extension of the CustomPainter.
class DrawFractal extends CustomPainter {
  var level = 10; // max level of fractal

  // Constructor that initializes the level of the fractal
  DrawFractal(value) {
    level = value;
  }

  // Recursively draw the fractal
  void fractal(Canvas canvas, int level) {
    if (level >= this.level) {
      return;
    }

    final paint = Paint()
      ..color = Colors.black
      ..strokeWidth = 1;

    // Recursively draw the left branch
    canvas.save();
    canvas.rotate(math.pi / 6);
    canvas.drawLine(Offset.zero, Offset(50 / level, 50 / level), paint);
    canvas.translate(50 / level, 50 / level);

    fractal(canvas, level + 1);
    canvas.restore();

    // As we go up the call stack, draw the right branch
    canvas.rotate(-math.pi / 6);
    canvas.drawLine(Offset.zero, Offset(50 / level, 50 / level), paint);
    canvas.translate(50 / level, 50 / level);
    fractal(canvas, level + 1);
  }

  /// Called when the canvas is (re)painted, perform the initial moving of the
  /// fractal to the center and other actions here such as the initial call to fractal.
  @override
  void paint(Canvas canvas, Size size) {
    fractal(canvas, 1);
  }

  /// Always repaint
  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    return true;
  }
}

// The code before here is to set up the flutter app and run it. You may not have to
// change this code.

/// Run the application
void main() => runApp(MyApp());

/// The application runs a streambuilder widget
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      // The title of my application
      title: 'My flutter application',
      home: StreamBuilderSetup(),
      debugShowCheckedModeBanner: false,
    );
  }
}

/// Stream to generate numbers from 1 to 10
Stream<int> generateNumbers = (() async* {
  await Future<void>.delayed(const Duration(seconds: 2));

  for (int i = 1; i <= 10; i++) {
    await Future<void>.delayed(const Duration(seconds: 1));
    yield i;
  }
})();

/// Setup a streambuild widget
class StreamBuilderSetup extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return _StreamBuilderSetupState();
  }
}

/// The innards of the streambuilder widget
class _StreamBuilderSetupState extends State<StreamBuilderSetup> {
  /// Boilerplate for initializing the state of the widget
  @override
  initState() {
    super.initState();
  }

  /// Build the widget, it consists of a title and a SizedBox where the
  /// drawing of the fractal (but could be anything takes place)
  /// Most of this is boilerplate code.
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        // Title bar for the widget
        title: const Text('Draw a Fractal in Flutter'),
      ),
      // Box in which to draw the fractal
      body: SizedBox(
        width: double.infinity,
        child: Center(
          child: StreamBuilder<int>(
            stream: generateNumbers,
            initialData: 0,
            builder: (
              BuildContext context,
              AsyncSnapshot<int> snapshot,
            ) {
              if (snapshot.connectionState == ConnectionState.waiting) {
                return Column(
                  crossAxisAlignment: CrossAxisAlignment.center,
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    const CircularProgressIndicator(),
                    Visibility(
                      visible: snapshot.hasData,
                      child: Text(
                        snapshot.data.toString(),
                        style:
                            const TextStyle(color: Colors.black, fontSize: 24),
                      ),
                    ),
                  ],
                );
              } else if (snapshot.connectionState == ConnectionState.active ||
                  snapshot.connectionState == ConnectionState.done) {
                if (snapshot.hasError) {
                  return const Text('Error');
                } else if (snapshot.hasData) {
                  return Center(
                    child: CustomPaint(
                        // Set up a canvas of size 500 by 5000
                        size: const Size(500, 500),
                        // Draw the fractal passing the level from the stream
                        painter: DrawFractal(snapshot.data)),
                  );
                } else {
                  return const Text('Empty data');
                }
              } else {
                return Text('State: ${snapshot.connectionState}');
              }
            },
          ),
        ),
      ),
    );
  }
}