Skip to content

Commit 3a79418

Browse files
committed
add quaternion tab
1 parent 51f6b34 commit 3a79418

File tree

4 files changed

+192
-1
lines changed

4 files changed

+192
-1
lines changed
+188
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
import 'package:flutter/material.dart';
2+
import 'package:vector_math/vector_math.dart' show Vector3, Quaternion;
3+
import 'dart:math' as math;
4+
5+
class QuaternionTab extends StatefulWidget {
6+
const QuaternionTab({super.key});
7+
8+
@override
9+
State<QuaternionTab> createState() => _QuaternionTabState();
10+
}
11+
12+
class _QuaternionTabState extends State<QuaternionTab> {
13+
double scale = 1.0;
14+
double xDegrees = 0.0;
15+
double yDegrees = 0.0;
16+
double zDegrees = 0.0;
17+
18+
// sphere datas
19+
double sphereRadius = 400;
20+
double numberOfSides = 9 * 4;
21+
double degrees = 10;
22+
23+
late double radians;
24+
late double cutHeight;
25+
26+
@override
27+
void initState() {
28+
radians = degrees * (math.pi / 180);
29+
cutHeight = sphereRadius * math.sin(radians);
30+
super.initState();
31+
}
32+
33+
@override
34+
Widget build(BuildContext context) {
35+
return Stack(
36+
children: [
37+
Transform(
38+
alignment: Alignment.center,
39+
transform: Matrix4.identity()
40+
..scale(scale)
41+
..rotateX(xDegrees / 180 * math.pi)
42+
..rotateY(yDegrees / 180 * math.pi)
43+
..rotateZ(zDegrees / 180 * math.pi),
44+
child: Stack(
45+
alignment: AlignmentDirectional.center,
46+
children: [
47+
...buildCuts(),
48+
const Divider(),
49+
const VerticalDivider(),
50+
],
51+
),
52+
),
53+
buildSliders(),
54+
],
55+
);
56+
}
57+
58+
List<Widget> buildCuts() {
59+
return [
60+
// for (int i = 1; i < 10; i++)
61+
// for (int j = 0; j < numberOfSides; j++)
62+
// buildCut(
63+
// axis: Vector3(1, 0, 0),
64+
// i: i,
65+
// j: j,
66+
// initialPoint: Vector3(
67+
// -i * cutHeight,
68+
// 0.0,
69+
// i * cutHeight / 2 - sphereRadius,
70+
// ),
71+
// ),
72+
// for (int i = 1; i < 10; i++)
73+
// for (int j = 0; j < numberOfSides; j++)
74+
// buildCut(
75+
// axis: Vector3(1, 0, 0),
76+
// i: i,
77+
// j: j,
78+
// initialPoint: Vector3(
79+
// i * cutHeight,
80+
// 0.0,
81+
// i * cutHeight / 2 - sphereRadius,
82+
// ),
83+
// ),
84+
85+
for (int j = 0; j < numberOfSides; j++)
86+
buildCut(
87+
axis: Vector3(1.0, 0.0, 0.0),
88+
i: 0,
89+
j: j,
90+
initialPoint: Vector3(
91+
0.0,
92+
0.0,
93+
sphereRadius,
94+
),
95+
),
96+
97+
for (int j = 0; j < numberOfSides; j++)
98+
buildCut(
99+
axis: Vector3(0.0, 1.0, 0.0),
100+
i: 0,
101+
j: j,
102+
initialPoint: Vector3(
103+
0.0,
104+
0.0,
105+
sphereRadius,
106+
),
107+
),
108+
];
109+
}
110+
111+
Widget buildCut({
112+
required Vector3 axis,
113+
required int i,
114+
required int j,
115+
required Vector3 initialPoint,
116+
}) {
117+
double angle = j * degrees * (math.pi / 180);
118+
Quaternion q = Quaternion.axisAngle(axis, angle);
119+
Vector3 point = q.rotate(initialPoint);
120+
121+
return Container(
122+
transform: Matrix4.identity()
123+
// ..setEntry(3, 2, 0.001)
124+
// ..rotateX(degreeX / 180 * math.pi)
125+
// ..rotateY(degreeY / 180 * math.pi)
126+
..translate(point.x, point.y, point.z),
127+
width: cutHeight,
128+
height: cutHeight,
129+
color: Colors.primaries[(i + j) % Colors.primaries.length],
130+
padding: const EdgeInsets.all(2.0),
131+
child: Text(
132+
'index\n$cutHeight',
133+
style: const TextStyle(fontSize: 10),
134+
),
135+
);
136+
}
137+
138+
Widget buildSliders() {
139+
return Column(
140+
children: [
141+
Slider.adaptive(
142+
value: scale,
143+
min: 0.1,
144+
max: 5.0,
145+
label: scale.toString(),
146+
onChanged: (value) {
147+
setState(() {
148+
scale = value;
149+
});
150+
},
151+
),
152+
Slider.adaptive(
153+
value: xDegrees,
154+
min: -360,
155+
max: 360,
156+
label: xDegrees.toString(),
157+
onChanged: (value) {
158+
setState(() {
159+
xDegrees = value;
160+
});
161+
},
162+
),
163+
Slider.adaptive(
164+
value: yDegrees,
165+
min: -360,
166+
max: 360,
167+
label: yDegrees.toString(),
168+
onChanged: (value) {
169+
setState(() {
170+
yDegrees = value;
171+
});
172+
},
173+
),
174+
Slider.adaptive(
175+
value: zDegrees,
176+
min: -360,
177+
max: 360,
178+
label: zDegrees.toString(),
179+
onChanged: (value) {
180+
setState(() {
181+
zDegrees = value;
182+
});
183+
},
184+
),
185+
],
186+
);
187+
}
188+
}

lib/pages/transform/transform_page.dart

+2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
import 'package:flutter/material.dart';
22
import 'package:flutter_projection/pages/transform/flipable_card_tab.dart';
3+
import 'package:flutter_projection/pages/transform/quaternion_tab.dart';
34

45
class TransformPage extends StatelessWidget {
56
const TransformPage({super.key});
67

78
@override
89
Widget build(BuildContext context) {
910
final tabs = [
11+
const QuaternionTab(),
1012
const FlipableCardTab(),
1113
];
1214

pubspec.lock

+1-1
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ packages:
161161
source: hosted
162162
version: "0.6.0"
163163
vector_math:
164-
dependency: transitive
164+
dependency: "direct main"
165165
description:
166166
name: vector_math
167167
sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"

pubspec.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ environment:
99
dependencies:
1010
flutter:
1111
sdk: flutter
12+
vector_math: ^2.1.4
1213

1314
dev_dependencies:
1415
flutter_test:

0 commit comments

Comments
 (0)