Skip to content

Instantly share code, notes, and snippets.

@sooxt98
Created June 17, 2022 23:01
Show Gist options
  • Save sooxt98/08032ef271eddac1c6ab78f806e9e305 to your computer and use it in GitHub Desktop.
Save sooxt98/08032ef271eddac1c6ab78f806e9e305 to your computer and use it in GitHub Desktop.
Phyllotaxis Visualizer Flutter
// Copyright 2019 the Dart project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file.
import 'dart:math' as math;
import 'package:flutter/material.dart';
const Color primaryColor = Colors.orange;
const TargetPlatform platform = TargetPlatform.android;
void main() {
runApp(Sunflower());
}
class SunflowerPainter extends CustomPainter {
final double seedRadius;
final double scaleFactor;
final double angle;
static const tau = math.pi * 2;
static final phi = (math.sqrt(5) + 1) / 2;
final int seeds;
SunflowerPainter(this.seeds, this.seedRadius, this.scaleFactor, this.angle);
@override
void paint(Canvas canvas, Size size) {
final center = size.width / 2;
for (var i = 0; i < seeds; i++) {
final theta = i * tau * (angle/360) / phi;
final r = math.sqrt(i) * scaleFactor;
final x = center + r * math.cos(theta);
final y = center - r * math.sin(theta);
final offset = Offset(x, y);
if (!size.contains(offset)) {
continue;
}
drawSeed(canvas, x, y);
}
}
@override
bool shouldRepaint(SunflowerPainter oldDelegate) {
return oldDelegate.seeds != seeds;
}
// Draw a small circle representing a seed centered at (x,y).
void drawSeed(Canvas canvas, double x, double y) {
final paint = Paint()
..strokeWidth = 2
..style = PaintingStyle.fill
..color = primaryColor;
canvas.drawCircle(Offset(x, y), seedRadius, paint);
}
}
class Sunflower extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return _SunflowerState();
}
}
class _SunflowerState extends State<Sunflower> {
double seeds = 100.0;
double seedRadius = 2.0;
double scaleFactor = 4.0;
double angle = 1.0;
int get seedCount => seeds.floor();
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData().copyWith(
platform: platform,
brightness: Brightness.dark,
sliderTheme: SliderThemeData.fromPrimaryColors(
primaryColor: primaryColor,
primaryColorLight: primaryColor,
primaryColorDark: primaryColor,
valueIndicatorTextStyle: const DefaultTextStyle.fallback().style,
),
),
home: Scaffold(
appBar: AppBar(
title: const Text("Sunflower"),
),
drawer: Drawer(
child: ListView(
children: const [
DrawerHeader(
child: Center(
child: Text(
"Sunflower 🌻",
style: TextStyle(fontSize: 32),
),
),
),
],
),
),
body: Container(
constraints: const BoxConstraints.expand(),
decoration: BoxDecoration(
border: Border.all(
color: Colors.transparent,
),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Container(
decoration: BoxDecoration(
border: Border.all(
color: Colors.transparent,
),
),
child: SizedBox(
width: 400,
height: 400,
child: CustomPaint(
painter: SunflowerPainter(seedCount, seedRadius, scaleFactor, angle),
),
),
),
Text("Showing $seedCount seeds"),
Text("Angle $angle seeds"),
ConstrainedBox(
constraints: const BoxConstraints.tightFor(width: 1300),
child: Slider.adaptive(
min: 1,
max: 1000,
value: seeds,
onChanged: (newValue) {
setState(() {
seeds = newValue;
});
},
),
),
ConstrainedBox(
constraints: const BoxConstraints.tightFor(width: 1300),
child: Slider.adaptive(
min: 1,
max: 10000,
value: seedRadius,
onChanged: (newValue) {
setState(() {
seedRadius = newValue;
});
},
),
),
ConstrainedBox(
constraints: const BoxConstraints.tightFor(width: 1300),
child: Slider.adaptive(
min: 1,
max: 100,
value: scaleFactor,
onChanged: (newValue) {
setState(() {
scaleFactor = newValue;
});
},
),
),
ConstrainedBox(
constraints: const BoxConstraints.tightFor(width: 1300),
child: Slider.adaptive(
min: 1,
max: 360,
value: angle,
onChanged: (newValue) {
setState(() {
angle = newValue;
});
},
),
),
],
),
),
),
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment