Skip to content

Commit f621a7d

Browse files
committed
aaa
1 parent ef676f8 commit f621a7d

5 files changed

Lines changed: 102 additions & 74 deletions

File tree

lib/MathForest/Geometry/D2/GMK/Core/GMKCompiler.dart

Lines changed: 34 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,15 @@ Vector(3, 4), type:Vector
4646
Vector(3.141592653589793, 3.141592653589793), type:Vector
4747
Vector(1, 0.0), type:Vector
4848
*/
49+
/*
50+
String.trim 移除字符串首尾的所有空白字符
51+
返回一个新的字符串,原始字符串不会被修改。仅移除首尾空白字符,字符串中间的任何空白字符都会保留
52+
空白字符定义: 包括空格、制表符(\t)、换行符(\n)等
53+
*/
54+
4955
List<dynamic> str2Factor(String str) {
5056
List<dynamic> factors = [];
51-
// 移除末尾的分号和空格
52-
str = str.trim(); // 移除空格
53-
if (str.endsWith(';')) {
54-
str = str.substring(0, str.length - 1).trim();
55-
}
57+
str = str.trim();
5658
// 按逗号分割,但要处理 < > 内的逗号
5759
List<String> parts = [];
5860
StringBuffer currentPart = StringBuffer();
@@ -66,7 +68,7 @@ List<dynamic> str2Factor(String str) {
6668
} else if (char == '>') {
6769
inAngleBrackets = false;
6870
currentPart.write(char);
69-
} else if (char == ',' && !inAngleBrackets) {
71+
} else if (char == ' ' && !inAngleBrackets) {
7072
// 不在尖括号内的逗号作为分隔符
7173
String part = currentPart.toString().trim();
7274
if (part.isNotEmpty) {
@@ -87,12 +89,13 @@ List<dynamic> str2Factor(String str) {
8789
part = part.trim();
8890
if (part.isEmpty) continue;
8991
if (part.startsWith('<') && part.endsWith('>')) {
90-
// 字符串类型,去掉尖括号
9192
String content = part.substring(1, part.length - 1);
92-
if (content.contains(',')) {
93+
if (content.contains(' ')) {
94+
//向量
9395
var f = str2Factor(content.trim());
9496
factors.add(Vector(f[0], f[1]));
9597
} else {
98+
//标签
9699
factors.add('#label<${content.trim()}>');
97100
}
98101
} else {
@@ -104,7 +107,6 @@ List<dynamic> str2Factor(String str) {
104107
return factors;
105108
}
106109

107-
108110
// 解析值
109111
dynamic _parseValue(String value) {
110112
if (value == '.T') return true;
@@ -128,6 +130,16 @@ dynamic _parseValue(String value) {
128130
}
129131

130132

133+
String extractAfter(String input, String? sign) {
134+
String sign_ = sign??' of ';
135+
final index = input.indexOf(sign_);
136+
if (index == -1) return '';
137+
final startIndex = index + sign_.length;
138+
if (startIndex >= input.length) return '';
139+
return input.substring(startIndex);
140+
}
141+
142+
131143
GMKStructure goCompiler(String source) {
132144
String source_ = removeComments(source);
133145
GMKStructure structure = GMKStructure.newBlank();
@@ -138,7 +150,7 @@ GMKStructure goCompiler(String source) {
138150
try {
139151
String label = subStringBetween(line, '@', ' is ').trim();
140152
String method = subStringBetween(line, ' is ', ' of ').trim();
141-
List<dynamic> factor = str2Factor(subStringBetween(line, ' of ', ';'));
153+
List<dynamic> factor = str2Factor(extractAfter(line, ' of '));
142154
structure.addStep(GMKCommand(method, label, factor));
143155
} on RangeError catch (e) {
144156
Exception('字符串解析错误: 在行中找不到必要的分隔符');
@@ -186,14 +198,14 @@ String adsorbConstNum(num n) {
186198

187199
// 吸附到常向量,以及分量数字
188200
String adsorbConstVec(Vector v) {
189-
if (v.x==1.0 && v.y==0.0){
201+
if (v.x == 1.0 && v.y == 0.0) {
190202
return '.I';
191-
} else if (v.x==0.0 && v.y==1.0){
203+
} else if (v.x == 0.0 && v.y == 1.0) {
192204
return '.J';
193-
} else if (v.x==0.0 && v.y==0.0){
205+
} else if (v.x == 0.0 && v.y == 0.0) {
194206
return '.O';
195207
} else {
196-
return '<${adsorbConstNum(v.x)}, ${adsorbConstNum(v.y)}>';
208+
return '<${adsorbConstNum(v.x)} ${adsorbConstNum(v.y)}>';
197209
}
198210
}
199211

@@ -202,27 +214,27 @@ String factor2Str(List<dynamic> factor) {
202214
String str = '';
203215
for (int i = 0; i < factor.length; i++) {
204216
dynamic item = factor[i];
205-
String division = (i + 1 == factor.length) ? ";" : ',';
217+
String division = (i + 1 == factor.length) ? "" : ' ';
206218
switch (item.runtimeType) {
207219
case const (String):
208220
if (item.startsWith('#label')) {
209-
str = '$str<${subStringBetween(item, '<', '>')}>$division ';
221+
str = '$str<${subStringBetween(item, '<', '>')}>$division';
210222
} else {
211-
str = '$str$item$division ';
223+
str = '$str$item$division';
212224
}
213225
case const (Vector):
214-
str = '$str${adsorbConstVec(item)}$division ';
226+
str = '$str${adsorbConstVec(item)}$division';
215227
case const (double):
216228
String s = adsorbConstNum(item);
217-
str = '$str$s$division ';
229+
str = '$str$s$division';
218230
case const (int):
219231
String s = adsorbConstNum(item);
220-
str = '$str$s$division ';
232+
str = '$str$s$division';
221233
case const (bool):
222-
str = '$str${item?'.T':'.F'}$division ';
234+
str = '$str${item ? '.T' : '.F'}$division';
223235
default:
224236
String s = item.toString();
225-
str = '$str$s$division ';
237+
str = '$str$s$division';
226238
}
227239
}
228240
return str;

lib/MathForest/Geometry/D2/GMK/Core/GMKCore.dart

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,8 @@ class GMKCore {
4949
for (var i = 1; i <= structureStepCount; i++) {
5050
GMKCommand itemGMKCommand = gmkStructure.indexStep(i);
5151
String label = itemGMKCommand.label;
52-
String type = lib.getTypeByMethod(itemGMKCommand.method);
53-
gmkData.data[label] = GraphOBJ(
54-
lib.run(itemGMKCommand, gmkData), label, type
55-
);
52+
var (obj, type) = lib.analysis(itemGMKCommand, gmkData);
53+
gmkData.data[label] = GraphOBJ(obj, label, type);
5654
}
5755
return gmkData;
5856
}

lib/MathForest/Geometry/D2/GMK/Core/GMKLib.dart

Lines changed: 49 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,16 @@
11
library;
22

3+
import '../../Linear/Vector.dart';
4+
import '../../Linear/Line.dart';
5+
import '../../Linear/Triangle.dart';
6+
import '../../Conic/Circle.dart';
7+
import '../../Conic/Conic0.dart';
8+
import '../../Conic/Conic1.dart';
9+
import '../../Conic/Conic2.dart';
10+
import '../../../../Algebra/Trunk/Fertile/DNum.dart';
11+
import '../../../../Algebra/Trunk/Fertile/QNum.dart';
12+
import '../../../../Algebra/Trunk/Fertile/TNum.dart';
13+
314
// 几何数据
415
import 'GMKData.dart';
516
// 几何结构
@@ -13,9 +24,6 @@ import 'GMKLib.dart' as lib;
1324
// 几何对象
1425
import '../Monxiv/GraphOBJ.dart';
1526

16-
import '../../Linear/Vector.dart';
17-
import '../../Linear/Line.dart';
18-
1927
dynamic getVar(itemFactor, gmkData) {
2028
if (itemFactor.runtimeType == String) {
2129
String label = compiler.subStringBetween(itemFactor, '<', '>');
@@ -25,63 +33,63 @@ dynamic getVar(itemFactor, gmkData) {
2533
}
2634
}
2735

28-
dynamic run(GMKCommand gmkCommand, GMKData gmkData) {
36+
dynamic analysis(GMKCommand gmkCommand, GMKData gmkData) {
2937
switch (gmkCommand.method) {
38+
case 'N':
39+
return (getVar(gmkCommand.factor[0], gmkData), 'num');
40+
41+
case 'DN':
42+
num n1 = getVar(gmkCommand.factor[0], gmkData);
43+
num n2 = getVar(gmkCommand.factor[1], gmkData);
44+
return (DNum(n1, n2), 'DNum');
45+
46+
case 'TN':
47+
num n1 = getVar(gmkCommand.factor[0], gmkData);
48+
num n2 = getVar(gmkCommand.factor[1], gmkData);
49+
num n3 = getVar(gmkCommand.factor[2], gmkData);
50+
return (TNum(n1, n2, n3), 'TNum');
51+
52+
case 'QN':
53+
num n1 = getVar(gmkCommand.factor[0], gmkData);
54+
num n2 = getVar(gmkCommand.factor[1], gmkData);
55+
num n3 = getVar(gmkCommand.factor[2], gmkData);
56+
num n4 = getVar(gmkCommand.factor[3], gmkData);
57+
return (QNum(n1, n2, n3, n4), 'QNum');
58+
3059
case 'P':
3160
num x = getVar(gmkCommand.factor[0], gmkData);
3261
num y = getVar(gmkCommand.factor[1], gmkData);
33-
return Vector(x, y);
62+
return (Vector(x, y), 'Vector');
63+
3464
case 'P:v':
35-
return getVar(gmkCommand.factor[0], gmkData);
65+
Vector p = getVar(gmkCommand.factor[0], gmkData);
66+
return (p, 'Vector');
67+
3668
case 'L':
3769
Vector p1 = getVar(gmkCommand.factor[0], gmkData);
3870
Vector p2 = getVar(gmkCommand.factor[1], gmkData);
39-
return Line.new2P(p1, p2);
71+
return (Line.new2P(p1, p2), 'Line');
72+
4073
case 'L:pv':
4174
Vector p = getVar(gmkCommand.factor[0], gmkData);
4275
Vector v = getVar(gmkCommand.factor[1], gmkData);
43-
return Line(p,v);
44-
case 'N':
45-
return getVar(gmkCommand.factor[0], gmkData);
46-
47-
48-
49-
76+
return (Line(p, v), 'Line');
5077

78+
case 'C:pr':
79+
Vector p = getVar(gmkCommand.factor[0], gmkData);
80+
num r = getVar(gmkCommand.factor[1], gmkData);
81+
return (Circle(p, r), 'Circle');
5182

52-
case 'P:mid':
83+
case 'P^mid':
5384
Vector p1 = getVar(gmkCommand.factor[0], gmkData);
5485
Vector p2 = getVar(gmkCommand.factor[1], gmkData);
55-
return p1.mid(p2);
86+
return (p1.mid(p2), 'Vector');
5687

57-
default :
58-
return null;
88+
default:
89+
return (null, '?type');
5990
}
6091
}
6192

62-
63-
64-
String getTypeByMethod(String method) {
65-
switch (method) {
66-
case 'P':
67-
return 'Vector';
68-
case 'N':
69-
return 'num';
70-
default :
71-
return '?type';
72-
}
73-
}
74-
75-
76-
77-
78-
79-
80-
81-
82-
83-
84-
8593
/*
8694
Map<String, dynamic> doc = {
8795
'P': {

lib/MathForest/Geometry/D2/GMK/Monxiv/main.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,10 @@ class Monxiv {
331331
Vector p = Vector(gmkData.data[key]?.obj);
332332
drawPoint(p, canvas, paint: defaultPaint);
333333
drawText('N: $key', p, 12, 500, canvas);
334+
case const ("Circle"):
335+
Circle circle = gmkData.data[key]?.obj;
336+
drawCircle(circle, canvas);
337+
drawText('Circle: $key', circle.p, 12, 500, canvas);
334338
default:
335339
drawText('error: $key', Vector(0, 0), 12, 500, canvas);
336340
}

lib/main.dart

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -116,9 +116,15 @@ class _MyHomePageState extends State<MyHomePage>
116116

117117
// 加载源码
118118
gmkCore.loadCode('''
119-
@A is P of 1, 1;
120-
@x is N of .E;
121-
@B is P of <x>, .PI;
119+
``@A is P of 1 1
120+
@x is N of .E
121+
@B is P of <x> .PI
122+
@C is P:v of <2 2>
123+
@D is P^mid of <C> <A>``
124+
125+
@qn1 is QN of 0 1 1.2 2
126+
@c is C:pr of .O 1
127+
122128
123129
124130
''');
@@ -630,7 +636,7 @@ class _MyHomePageState extends State<MyHomePage>
630636
}
631637

632638
String str =
633-
'1, 1.23, .PI, .NAN, .INF, a, <b>, .T, <3,4>, <1.23, 4.56>, <.PI, .PI>, <.NAN, .INF>, .I;';
639+
'1 1.23 .PI .NAN .INF a <b> .T <3 4> <1.23 4.56> <.PI .PI> <.NAN .INF> .I';
634640
m(
635641
'-----------原始-----------',
636642
);
@@ -690,9 +696,9 @@ class _MyHomePageState extends State<MyHomePage>
690696
}
691697

692698
String code = '''
693-
@A is P of 1, 1;
694-
@c is C of .O, <.PI,0>;
695-
@l is L of <A>, .I;
699+
@A is P of 1 1
700+
@c is C of .O <.PI 0>
701+
@l is L of <A> .I
696702
''';
697703
lll();
698704
m('gmk源代码\n$code');

0 commit comments

Comments
 (0)