其中采用了自定义公式来描述参数的变化将导致的图形变化。例如对于厚度的变化,定义的公式为:“dotAll.x=dotAll.x*t1/dot1.y;dotAll.y=dotAll.y*t1/dot1.y;”。这个公式表示对于图形中的所有点,当厚度变化时,点的x坐标变为 原x坐标值乘以新的厚度,再除以原来的序号为1的点的y坐标(即原来的厚度),同理对于y坐标的变化也一样。
最终公式将解析成 x=2.0 * 3 / 1.5, 最终结果为 4.0。问题的焦点在于如何将“2.0 * 3 / 1.5”这种字符串的表达式,让计算机能理解,并计算出结果。这里我采用了“逆波兰式算法”来解决这个问题。
关于“逆波兰式算法”的具体内容,请看这里 http://baike.baidu.com/view/2582.htm ,里面解释得很好。
最终程序里面的算法描述如下 :
下面我们来具体实现下这个算法,代码中注释较全,就不详细解说了。
首先,我们来定义下操作数类。
1 /// <summary>
2 /// 操作数类型
3 /// </summary>
4 public enum OperandType
5 {
6 /// <summary>
7 /// 函数
8 /// </summary>
9 FUNC = 1,
10
11 /// <summary>
12 /// 日期
13 /// </summary>
14 DATE = 2,
15
16 /// <summary>
17 /// 数字
18 /// </summary>
19 NUMBER = 3,
20
21 /// <summary>
22 /// 布尔
23 /// </summary>
24 BOOLEAN = 4,
25
26 /// <summary>
27 /// 字符串
28 /// </summary>
29 STRING = 5
30
31 }
2 /// 操作数类型
3 /// </summary>
4 public enum OperandType
5 {
6 /// <summary>
7 /// 函数
8 /// </summary>
9 FUNC = 1,
10
11 /// <summary>
12 /// 日期
13 /// </summary>
14 DATE = 2,
15
16 /// <summary>
17 /// 数字
18 /// </summary>
19 NUMBER = 3,
20
21 /// <summary>
22 /// 布尔
23 /// </summary>
24 BOOLEAN = 4,
25
26 /// <summary>
27 /// 字符串
28 /// </summary>
29 STRING = 5
30
31 }
1 public class Operand
2 {
3 #region Constructed Function
4 public Operand(OperandType type, object value)
5 {
6 this.Type = type;
7 this.Value = value;
8 }
9
10 public Operand(string opd, object value)
11 {
12 this.Type = ConvertOperand(opd);
13 this.Value = value;
14 }
15 #endregion
16
17 #region Variable & Property
18 /// <summary>
19 /// 操作数类型
20 /// </summary>
21 public OperandType Type { get; set; }
22
23 /// <summary>
24 /// 关键字
25 /// </summary>
26 public string Key { get; set; }
27
28 /// <summary>
29 /// 操作数值
30 /// </summary>
31 public object Value { get; set; }
32
33 #endregion
34
35 #region Public Method
36 /// <summary>
37 /// 转换操作数到指定的类型
38 /// </summary>
39 /// <param name="opd">操作数</param>
40 /// <returns>返回对应的操作数类型</returns>
41 public static OperandType ConvertOperand(string opd)
42 {
43 if (opd.IndexOf("(") > -1)
44 {
45 return OperandType.FUNC;
46 }
47 else if (IsNumber(opd))
48 {
49 return OperandType.NUMBER;
50 }
51 else if (IsDate(opd))
52 {
53 return OperandType.DATE;
54 }
55 else
56 {
57 return OperandType.STRING;
58 }
59 }
60
61 /// <summary>
62 /// 判断对象是否为数字
63 /// </summary>
64 /// <param name="value">对象值</param>
65 /// <returns>是返回真,否返回假</returns>
66 public static bool IsNumber(object value)
67 {
68 double val;
69 return double.TryParse(value.ToString(), out val);
70 }
71
72 /// <summary>
73 /// 判断对象是否为日期
74 /// </summary>
75 /// <param name="value">对象值</param>
76 /// <returns>是返回真,否返回假</returns>
77 public static bool IsDate(object value)
78 {
79 DateTime dt;
80 return DateTime.TryParse(value.ToString(), out dt);
81 }
82 #endregion
83 }
2 {
3 #region Constructed Function
4 public Operand(OperandType type, object value)
5 {
6 this.Type = type;
7 this.Value = value;
8 }
9
10 public Operand(string opd, object value)
11 {
12 this.Type = ConvertOperand(opd);
13 this.Value = value;
14 }
15 #endregion
16
17 #region Variable & Property
18 /// <summary>
19 /// 操作数类型
20 /// </summary>
21 public OperandType Type { get; set; }
22
23 /// <summary>
24 /// 关键字
25 /// </summary>
26 public string Key { get; set; }
27
28 /// <summary>
29 /// 操作数值
30 /// </summary>
31 public object Value { get; set; }
32
33 #endregion
34
35 #region Public Method
36 /// <summary>
37 /// 转换操作数到指定的类型
38 /// </summary>
39 /// <param name="opd">操作数</param>
40 /// <returns>返回对应的操作数类型</returns>
41 public static OperandType ConvertOperand(string opd)
42 {
43 if (opd.IndexOf("(") > -1)
44 {
45 return OperandType.FUNC;
46 }
47 else if (IsNumber(opd))
48 {
49 return OperandType.NUMBER;
50 }
51 else if (IsDate(opd))
52 {
53 return OperandType.DATE;
54 }
55 else
56 {
57 return OperandType.STRING;
58 }
59 }
60
61 /// <summary>
62 /// 判断对象是否为数字
63 /// </summary>
64 /// <param name="value">对象值</param>
65 /// <returns>是返回真,否返回假</returns>
66 public static bool IsNumber(object value)
67 {
68 double val;
69 return double.TryParse(value.ToString(), out val);
70 }
71
72 /// <summary>
73 /// 判断对象是否为日期
74 /// </summary>
75 /// <param name="value">对象值</param>
76 /// <returns>是返回真,否返回假</returns>
77 public static bool IsDate(object value)
78 {
79 DateTime dt;
80 return DateTime.TryParse(value.ToString(), out dt);
81 }
82 #endregion
83 }