探索WPF中的绘图/绘图者空间范式

视觉艺术家和数据可视化专家为何如此偏爱Processing,而WPF明明可以做得更好?这是在购买一本关于Processing的书籍时想要解答的问题……以下是发现。

Processing的简洁之美

Processing专注于绘图,通过限制其应用范围,简化了用户的操作(尽管理论上可以用它做任何事情,但用它来创建一个完整的应用程序会非常繁琐)。

Processing区分了“绘图空间”和“绘图者空间”。

绘图/绘图者空间范式

在“绘图/绘图者空间”范式中,画一条45度角、长度为10的线,需要将纸张旋转45度,然后画一条长度为10的直线。而在“仅绘图空间”范式中,需要使用三角函数规则计算线的第二个点的坐标:end.X = COS(45) * 10, end.Y = SIN(45) * 10。然后画线到这个点。

复杂绘图的示例

在“仅绘图空间”范式中,要画一个十字,需要指定所有坐标。在纯XAML中,它看起来是这样的:

<Path x:Name="path" Data="M 0 0 L 5 0 L 5 -5 L 10 -5 L 10 0 L 15 0 L 15 5 L 10 5 L 10 10 L 5 10 L 5 5 L 0 5 Z" Stretch="Uniform" Fill="LightBlue" Stroke="Black">

另一方面,在“绘图/绘图者空间”范式中,只需要指定如何画它,通过移动铅笔和旋转纸张。这里,只指定了手和纸张的移动来画它。

<Path local:GeometryProperties.Data="L 5 ROT -90 L 5 ROT 90 L 5 ROT 90 L 5 ROT -90 L 5 ROT 90 L 5 ROT 90 L 5 ROT -90 L 5 ROT 90 L 5 ROT 90 L 5 ROT -90 L 5 ROT 90 L 5 ROT 90 F Z" Stretch="Uniform" Fill="LightBlue" Stroke="Black">

ProcessingContext类

将最重要的类命名为ProcessingContext,这个名字启发了想法。每个方法都会修改在构造函数中传递的GeometryGroup:

public ProcessingContext(GeometryGroup group) { _Path = new PathGeometry(); _Geometries = group; _Geometries.Children.Add(_Path); }

深入理解矩阵的力量

如所见,ProcessingContext类持有一个_CurrentTransform,这个变换可以将任何点在绘图空间和绘图者空间之间来回转换。每次变换基础都会改变_CurrentTransform,它内部只是一个Transform(它里面持有一个Matrix)。

[GeometryCommand("ROT")] public void Rotate(double degree) { var rotation = new RotateTransform(degree) { CenterX = _Origin.X, CenterY = _Origin.Y }; this.PushTransform(rotation); }

Processing无疑是一种创建强大视觉效果的好方法……但对于一个了解通用编程语言的开发者来说,它的真正力量在于其绘图范式。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485