Reputation: 49
I was trying to build a fourier series illustration I found and I was very close to completing when this weird problem occurred. The first illustration in this part of the wikipedia page is what I am trying to recreate. As you slide the slider forward it starts to approach a square wave pretty well. But abruptly, it starts to connect lines weirdly and make a mess out of it.
Here is the current code. The testing is what has to be called in the home of the MaterialApp
:
import 'package:flutter/material.dart';
import "dart:math";
class Testing extends StatefulWidget {
const Testing({super.key});
@override
State<Testing> createState() => _TestingState();
}
class _TestingState extends State<Testing> with SingleTickerProviderStateMixin {
late AnimationController _controller;
late Animation _animation;
late double _value = 1;
@override
void initState() {
super.initState();
_controller =
AnimationController(vsync: this, duration: Duration(seconds: 5));
_animation = Tween(begin: 2 * pi, end: 0.0).animate(_controller);
_controller.forward();
_controller.addListener(() {
if (_animation.isCompleted) {
_controller.reset();
_controller.forward();
}
setState(() {});
});
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
Slider(
min: 1,
max: 100,
divisions: 100,
value: _value,
onChanged: (new_value) => _value = new_value,
),
SizedBox(
height: 500,
width: MediaQuery.sizeOf(context).width,
child: ClipRRect(
child: CustomPaint(
painter: Sky(
angle: _animation.value,
running: _controller.isAnimating,
value: _value.toInt()),
size: Size(MediaQuery.sizeOf(context).width, 500),
),
)),
],
));
}
}
List<Offset> wave = [];
class Sky extends CustomPainter {
bool running;
double angle;
int value;
Sky({required this.angle, required this.running, required this.value});
@override
void paint(Canvas canvas, Size size) {
var paint = Paint()
..color = Colors.black
..strokeWidth = 1.0
..style = PaintingStyle.stroke;
double centerX = 100;
double centerY = size.height / 2;
canvas.translate(centerX, centerY);
double circleRadius = 80 * (4 / (1 * pi));
double x1 = 0;
double y1 = 0;
for (int i = 0; i < value; i++) {
double prevx = x1;
double prevy = y1;
int n = (i * 2) + 1;
circleRadius = 80 * (4 / (n * pi));
x1 += circleRadius * cos(n*angle);
y1 += circleRadius * sin(n*angle);
canvas.drawCircle(Offset(prevx, prevy), circleRadius, paint);
canvas.drawLine(Offset(prevx, prevy), Offset(x1, y1), paint);
}
double waveValue = running ? y1 : 0;
wave.insert(0, Offset(240, y1));
// wave = wave.map((e) => e.translate(wave.indexOf(e).toDouble(), 0)).toList();
if (running) {
canvas.drawLine(Offset(x1, y1), Offset(240, y1), paint);
}
List<Offset> wave2 =
wave.map((e) => e.translate(wave.indexOf(e).toDouble(), 0)).toList();
// canvas.drawPoints(PointMode.lines, wave2, paint);
Path path = Path();
path.moveTo(wave2[0].dx, wave2[0].dy);
for (int i = 1; i < wave2.length; i++) {
path.lineTo(wave2[i].dx, wave2[i].dy);
}
for (int i = wave2.length-1; i > 1; i--) {
path.lineTo(wave2[i].dx, wave2[i].dy);
}
canvas.drawPath(path, paint);
if (wave.length > 1000) {
wave.removeLast();
}
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return true;
}
}
I have tried drawing the wave using drawPoints (all the point modes), draw vertices. I have also tried using for loops to individually draw lines from every one point in the wave2 list to every subsequent one but the problem persists. I want to figure out as to how I can use the list of points called wave2 and connect them to draw a wave.
Upvotes: 0
Views: 70