Engee 文档

转换,转换和投影管道

该页面正在翻译中。

本节介绍了在绘图显示过程中应用于数据的所有处理阶段。

概览

管道大致可以概括为三个部分,每个部分有几个步骤:

  1. 主要归一化类型的转换

    1. expand_dimensions() 添加默认/生成的数据(例如x,y 图像())

    2. dim_convert 处理特殊类型,如单元

    3. convert_arguments() 规范化数值类型和数据格式

  2. 以每个图为基础变换数据的变换

    1. 变换_func 是应用于数据的函数

    2. 模型 矩阵应用线性变换

  3. 将数据从一个坐标系投影到另一个坐标系的投影

    1. 查看 矩阵将数据从"世界"空间移动到相机"视图/眼睛"空间

    2. 投影;投影 矩阵从相机空间移动到"剪辑"空间

    3. 视区 将"剪辑"空间移动到"像素/屏幕"空间

作为 用户,您可以直接控制 模型 矩阵(1.2)与 规模!(), 翻译!()旋转!() 函数。 你可以间接控制投影(3) 空间 属性。 它设置用作初始空间的坐标系,并调整投影结果。 你也有间接控制 变换_func,可以通过传递一个 转变() 直接到一个情节。 然而,它通常由 轴心,轴心.

作为 开发人员,即想要扩展Makie的人,您可以与大多数这些步骤进行交互。 很可能你会扩展 convert_arguments() 允许绘制特殊类型。 但是你也可以实现更多的dim_converts,添加方法 expand_dimensions(),实现更多的变换功能或添加一个产生自己的相机查看投影;投影矩阵。 只有模型视区处理及解释空间 都准备好了。

参数转换

调用plot函数时,例如 分散!(axis_or_scene,args。..) 构造一个新的plot对象。 它跟踪原始输入参数作为一个可观察的 情节。阿格斯. 然后,这些输入参数由转换管道转换并存储在 情节。转换后的. 管道由3个步骤组成,如上所述:

数据生成

第一步是生成"缺失"数据。 例如,您可以创建一个图像图,只需 图像(rand(10,10)). 然而,最一般的形式也包括 关闭中间值 对于x和y维度,声明图像的大小。 此数据由 expand_dimensions(::Trait,args...) 在哪里 特质=conversion_trait(::PlotType,args...).

特殊类型加工

第二步处理特殊类型,如 单位 类别, 日期 需要在场景中同步的类型或类别值。 例如,如果一个图使用"小时"作为其x值的单位,则其他图也需要使用x的时间单位。如果单位的比例在不同的图之间不同,即一个使用小时,另一个使用分钟,那么必须找到一个公共单位,并且需要适当地缩放这些值。 这就是 dim_converts 处理的内容。 你可以在 维度转换文档。

转换参数

转换管道中的最后一步和主要工作-马是 convert_arguments() 函数。 它的目的是将不同的数据类型和布局转换为一种或几种选择的格式。 例如,传递给 散点() 被转换为一个 向量资料{Point{D, T}} 哪里 D=23T=浮32漂浮64. 这些转换可以根据绘图类型或其转换特征进行。 为 散点() 转换特性 以点为基础的 被使用。 convert_arguments() 也可以接受来自情节属性的关键字参数。 为此,属性需要标记为 used_attribute(::PlotType)=(名称。..). 该列表中的任何名称都将从最终绘图的属性中删除,并传递到 convert_arguments() 相反。

如果您想绘制自己的自定义类型,您可能需要扩展 convert_arguments(). 假设你有一些自定义类型 神秘感,神秘感 和一些功能 职位(::MySimulation) 它返回调用时要绘制的位置 分散(::MySimulation). 在这种情况下,您可以定义

function Makie.convert_arguments(PT::PointBased, sim::MySimulation)
    return Makie.convert_arguments(PT, positions(sim))
end

让这成为可能。 您可以使用绘图类型(即 散点,散点)作为第一个论点。

变换

转换将绘图数据的类型和布局标准化后,转换现在可以对其进行调整。 它们由 转型 对象,它同时存在于情节和场景层面的 转型 场。 它包含一个 变换_func 它是一个应用于数据的类似函数的对象,以及一个 模型 处理数据线性变换的矩阵。

情节 转型 对象可以继承自它的父场景或情节,如果它在相同的行为 空间. 为 变换_func 这意味着使用与父级相同的函数。 为 模型 这意味着合并父母 模型 与本地矩阵为 情节。模型=父。模型*local_model.

变换函数

的变换函数或 变换_func转型 对象。 它处理非线性变换,如对数轴的对数变换。

每个 变换_func 至少实现

Makie.apply_transform(transform_func, arg::VecTypes{N, T}) where {N, T}

其中变换函数可以用任何类型表示,而不仅仅是一个 功能. 这样它就可以携带对变换可能很重要的辅助信息。 另外方法与其他 arg,arg 类型,例如 向量资料也可以实现其s以更有效地应用transform_func。

通常一个transform_func也实现

Makie.inverse_transform(transform_func)
Makie.apply_transform(transform_func, arg::Rect3)

逆允许将数据转换回来,例如在轴限制中使用。 如果一个合理的逆存在(即使它是不完整的或不明确的),它应该由 逆转录病毒. 另一个 apply_翻译 方法用于 装订箱() 并默认转换边界框的角。 如果默认值返回错误的结果,例如使用极坐标变换,则应该实现它。

模型转换

模型矩阵负责绘图数据的线性变换。 这包括缩放与 规模!(),翻译与 翻译!() 和旋转与 旋转!(). 查看 转换参考文档以获取更多细节。

预测

投影是将数据从一个坐标系或"空间"移动到另一个坐标系的矩阵变换。 矩阵是 相机(场景) 并由 cameracontrols(场景) 或由父母 . 该图不能改变这些矩阵,但可以控制哪些将通过 空间 属性。

相机控制器

相机控制器,无论是场景中的对象还是父块,都会生成 查看投影;投影 矩阵。 这些矩阵存储在 相机(场景) 这也将它们结合成 projectionview=投影*视图. 该 查看 matrix将绘图数据从"世界"坐标系移动到基于查看器的居中和定向。 该坐标系通常称为相机、眼睛或视图空间。 从那里 投影;投影 矩阵可以应用透视投影和缩放数据移动到"剪辑"空间。 这个空间是一个归一化的空间,其中a-1之外的所有东西。. 1个盒子被夹住了。 最终投影到像素或屏幕空间由图形API隐式处理,或在CairoMakie中显式处理,基于 视口(场景). 该 相机(场景) 还持有到一个 像素空间 矩阵,它将像素空间转换为剪辑空间,场景分辨率以及相机方向的一些辅助信息。 请注意,相机控制器通常被称为"相机",因为 相机(场景) 只是不活动的存储。

空间属性

空间 属性控制绘图使用的投影矩阵。 这些选项指的是输入空间,它通常转换为剪辑空间。 选项 include:

  • 空间=:数据:应用相机 查看投影;投影 矩阵。 (这通常在图形Api中称为世界空间。)

  • 空间=:像素:应用相机 像素空间 矩阵。

  • 空间=:剪辑:应用单位矩阵。

  • 空间=:相对:应用恒定的平移尺度矩阵。

请注意,所有这些都在转换后起作用,即在 模型 矩阵进行应用。

标记空间属性

一些地块包括一个 标记空间 属性。 对于这些,上面的投影分为两个步骤,从 空间标记空间 以剪辑空间。 与上述相同的选项也适用。 如果需要,这些矩阵中的一些也可能被反转(例如从:像素->:数据->:剪辑空间)。

浮式32转换

Float32Convert是一个可选的步骤,它不适合完全进入管道。 它的工作是确保数据,投影矩阵和模型矩阵被保存以转换为Float32类型,从而可以传递给图形API而不会出现精度问题。

目前只 轴心,轴心 实际上定义了这种转换。 打电话时 剧情!(轴,。..)数据限制() 该图由轴记录,并与现有的限制相结合。 限制最终触发相机更新,其中 变换_func 得到应用。 结果传递给 浮式32转换,其更新其线性变换以使变换后的限制Float32-安全。 然后从安全极限导出投影矩阵。 此时Float32Convert的线性变换就存在于之前 查看. 如果可能的话,它是permuted与 模型 使得模型矩阵可以由图形API处理,即在GPU上。