Created
April 18, 2022 00:43
-
-
Save hathibelagal-dev/5275ed6ee6452167a2d55f9237f4cf63 to your computer and use it in GitHub Desktop.
Clifford attractor in a Flutter app
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:flutter/material.dart'; | |
import 'dart:math' as Math; | |
import 'dart:async'; | |
import 'dart:ui'; | |
void main() { | |
runApp(const MyApp()); | |
} | |
class MyApp extends StatelessWidget { | |
const MyApp({Key? key}) : super(key: key); | |
@override | |
Widget build(BuildContext context) { | |
return MaterialApp( | |
title: 'Attractor', | |
theme: ThemeData( | |
brightness: Brightness.dark | |
), | |
home: const MyHomePage(title: 'Clifford Attractor'), | |
); | |
} | |
} | |
class MyHomePage extends StatefulWidget { | |
const MyHomePage({Key? key, required this.title}) : super(key: key); | |
final String title; | |
@override | |
State<MyHomePage> createState() => _MyHomePageState(); | |
} | |
class CliffordAttractorPainter extends CustomPainter { | |
List<Offset> points; | |
CliffordAttractorPainter(this.points) : super(); | |
@override | |
void paint(Canvas canvas, Size size) { | |
Paint paint = Paint(); | |
paint.color = Colors.yellow.withOpacity(0.7); | |
paint.style = PaintingStyle.fill; | |
paint.strokeWidth = 1; | |
canvas.drawPoints(PointMode.points, points, paint); | |
} | |
@override | |
bool shouldRepaint(CliffordAttractorPainter oldDelegate) { | |
return true; | |
} | |
} | |
class _MyHomePageState extends State<MyHomePage> { | |
num _a = -1.24; | |
num _b = -1.2; | |
num _c = -1.81; | |
num _d = -1.9; | |
Offset _currentOffset = Offset(0, 0); | |
List<Offset> _points = []; | |
int _count = 0; | |
int _maxPoints = 100000; | |
int _pointsPerCalculation = 10000; | |
num _change = -1; | |
void calculate() { | |
if(_count > _maxPoints) { | |
setState(() { | |
_b += 0.01 * _change; | |
_count = 0; | |
if(_b < -2.11 || _b > -1.2) { | |
_change *= -1; | |
} | |
}); | |
return; | |
} | |
if(_points.length > _maxPoints) { | |
_points.removeRange(0, _pointsPerCalculation); | |
} | |
for(var i=0;i<_pointsPerCalculation;i++) { | |
Offset o = Offset( | |
Math.sin(_a * _currentOffset.dy) + _c * Math.cos(_a * _currentOffset.dx), | |
Math.sin(_b * _currentOffset.dx) + _d * Math.cos(_b * _currentOffset.dy) | |
); | |
_count += 1; | |
_points.add(Offset(60 * _currentOffset.dx + 190, 90 * _currentOffset.dy + 300)); | |
_currentOffset = o; | |
} | |
setState(() { | |
_points = _points; | |
}); | |
} | |
@override | |
void initState() { | |
Timer.periodic(const Duration(milliseconds: 20), (_) { calculate(); }); | |
} | |
@override | |
Widget build(BuildContext context) { | |
return Scaffold( | |
appBar: AppBar( | |
title: Text(widget.title), | |
), | |
body: CustomPaint( | |
painter: CliffordAttractorPainter(_points) | |
) | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment