== 编程命名约定


+ 对象属性命名一般使用小写，命名写全，一般不使用下划线连接单词, 如 `maxlength`
+ 私有属性前加下划线,如 `_previous`
+ 类属性和全局变量命名大写，可加下划线, 如 `MAX_NUM`
+ 方法写简称，加下划线，一般以谓词结构命名，如 `get_ctx,set_ctx`
+ 与内部其他部分属性相配合的属性都设为私有属性，相应的设立对应的只读属性用于读取使用。如果需要更改，一般使用方法进行更改和读写。

== 参数设置


=== 位置的表示方法


用户操作的坐标为相对数据坐标，对应的表示方法：

+ XY直角坐标系表示
   
   坐标可以使用字典表示, 如`{x:1};{y:1};{x:1,y:2}`,也可以使用二元数组表示 `(a,b)`。如果支持z轴，则可以使用三维数组表示。

+ 当前坐标
   
   可以使用空字典表示,或者空数组表示。 如 `{} 、 ()`

+ 相对坐标

   相对于当前坐标的表示，可以使用字典中的rel键表示， 如 `{rel:(a,b)}; {rel:{x:1,y:2}};` 

+ 极坐标

   极坐标使用角度和半径表达。角度由角度字符串 `"30deg"` 表示，弧度由数字表示。 
   可以使用字典和二元数组表示，如 `{angle:"30deg",radius: 1}; ("30deg",1)`

+ 绝对数据坐标系
   
   可以直接指定绝对数据坐标系，这点在使用锚点系统中十分便利，使用字典中abs键表示， 如 `{abs:(a,b)}`

+ 指定当前位置不更新
   
   使用update键可以指定当前位置不发生改变，如 `{update: False}` 。默认为True会发生改变。
   
=== 样式的表示方法

略

=== 单位的表示方法

略

=== 锚点的表示方法

略

== 绘图流程

一般的绘图函数具有以下流程：

+ 确定坐标点的位置

   pytez的坐标表示是一个具有状态的坐标系，其基础是一个二维直角坐标系称为绝对数据坐标系，在此之上用户输入的数据是相对数据坐标系，没有进行任何设置
   之前，相对坐标系和绝对坐标系一致，绝对坐标系的关系由原点位置+变换矩阵决定。其状态性还体现在当前坐标位置的保存，当前坐标位置以相对数据坐标系表示，
   初始状态下相对坐标系位于原点。原点位置和变换矩阵都可以通过方法设置，当前位置随着绘画的过程改变，也可以通过方法设置，当前位置可以通过传入空数组表示。

   pytez还支持在当前相对坐标系下建立子坐标系，通过确定子坐标系在相对数据坐标系中的位置大小单位，来建立子坐标系，本质上是坐标的缩放变换。可以通过还原变换矩阵复原。
   
   参见：
    目前暂时使用变换矩阵完成，后面研究变换矩阵的变换范围或再做取舍。变换矩阵并不能完成相对于绝对单位平移的操作，这里有两种解决方法，一种是坐标维度+1，用`(x,y,1)`来表示变换时的坐标，这样的变换矩阵维度+1。另一种方法是设置原点，这里采用和typst相同的4维变换矩阵来表示变换。
   
  #link("https://zh.wikipedia.org/wiki/%E5%8F%98%E6%8D%A2%E7%9F%A9%E9%98%B5")

   注：为了增加平移的支持，从而设置

+ 确定绘图尺寸和类型

   pytez的绘图尺寸通过长度单位设置，在Canvas类初始化时就可以设置单位长度的尺寸，后面的绘图一般都是基于单位长度绘图的。
   但是matplotlib提供了多种坐标系绘图，而typst提供了多种绝对长度尺寸的设置。matplotlib的设计功能更为强大，typst的多种绝对长度尺寸
   设计也具有其便利性。设计初期只实现相对于单位长度的支持
+ 确定绘图变换

   影响最终图形的形状的要素还有matplotlib的变换，一般而言不使用其就可以完成大部分工作，但是当需要针对matplotlib多种坐标系设计图形时就需要用到。
   确定绘图变换pytez不做过多设计，是以patch类的参数传递的，需要了解matplotlib的transform属性以使用。
+ 确定绘图的样式
   
   pytez的基本图形以具有填充色和轮廓线的封闭图形表示，也可以单独绘制线型。2维封闭图形的样式具有fill和stroke两项，1维线型则只具有stroke属性，fill属性将被忽略。
   广义的样式还包括图形的尺寸默认参数，例如圆的默认半径为1。marker的箭头形状、长度等等。所以前面的绘图尺寸和类型的确定最后也作用于广义的样式之中。

+ 生成图形类
   
   图形基于坐标，广义样式以及mpl的patch属性生成图形类。当patch属性和其他属性冲突时，优先其他属性。

+ 添加到Axes
   
   将生成图形类添加到Axes的children中，交于matplotlib处理。

== 主要类型的设计


=== Canvas类的设计


pytez支持许多特性，综合考虑这些特性来设计的Canvas类，目的是简化几何图的绘制，而不是数据作图。

+ 数据坐标系统。

   Canvas具有以下属性和方法来支持坐标表示:

   属性,包括不建议调用的私有属性: 

   + \#被上下文管理器取代:: `Canvas._curpos` 获取当前坐标位置
   + \#被上下文管理器取代:: `Canvas._transform` \#用变换矩阵类代替:: `Canvas._matrix` 获取变换矩阵
   + \#被维度+1的变换矩阵取代:: `Canvas._origin` 相对坐标系原点在绝对坐标系中的位置
   + \#被废除，一律采用变换矩阵，设计变换矩阵类后计算优化也才类中处理:: `Canvas._transformed` 变换矩阵是否起作用
   + `Canvas._prematrixes` 使用过的变换矩阵，默认最多存储15项
   + `Canvas._maxprematrixes` 使用过的变换矩阵序列的最大长度，默认为15。可以直接访问设置，必须为整数
   + `Canvas._bounds` 相对数据坐标系边界，默认为None，指无穷,必须为正值。
   + `Canvas._context` 上下文属性是一个上下文类，保存着Canva的当前状态，包括length,transform,debug。
   + `Canvas.context` 读、部分可写,返回上下文管理器(set_ctx)
   + `Canvas.curpos` 读写，返回当前位置， (moveto)
   + `Canvas.transform` 读写,返回变换矩阵，(set_tansform)
   + `Canvas.bounds` 读写，返回边界，(set_bounds)
   + `Canvas.maxpromatrixes` 读写，返回变换矩阵缓存数
   + `Canvas.prematrixes` 只读，返回变换矩阵缓存序列

   方法:

   + `Canvas.get_curpos()` 获取相对数据坐标表示下的当前坐标位置
   + `Canvas.moveto(pos)` 设置相对数据坐标表示下的当前坐标位置
   + `Canvas.set_transform(mat)` 设置变换矩阵，参数可以是4x4变换矩阵或者变换矩阵类。
   + `Canvas.rotate(angle,origin=(0,0))`  过点绕轴旋转，在只支持二维条件下默认为z轴，如果支持三维，则angle参数可以传入字典指定其旋转轴,如`{x:"45deg",y:"15deg"}`
   + `Canvas.translate(vetc)` 传入坐标视为矢量，向其平移
   + `Canvas.scale(s)` 传入字典，使其放缩，如, {x:0.5,y:0.5}
   + `Canvas.set_origin(pos)`  设置坐标轴原点
   + `Canvas.set_viewport(from,to,bounds)` 设置子坐标系，原理也是变换矩阵完成，所以边界没有限制
   + `Canvas.set_bounds(bounds=None)` 设置当前坐标系的边界,None表示无限制。
   + `Canvas.get_origin()` 获取绝对坐标系表示下的原点位置
   + `Canvas.get_ctx` 获取上下文,即坐标系的状态
   + `Canvas.set_ctx(mat,length,debug,zorder)` 设置上下文，即坐标系的状态。

+ 图层

   matplotlib库中也支持图层的设置，通过绘图时指定zorder参数完成。pytez在此基础上支持通过图层设置函数设置当前图层。

   属性,包括不建议调用的私有属性：

   + `Canvas._zorder` 当前图层序号 
   + `Canvas.zorder` 只读

   方法: 

   + `Canvas.set_layer(zorder)` 这里与typst不同，这是由于typst的参数可以传递代码块(内容)。 所以将当前图层设置为状态属性。

+ 样式

   pytez的样式支持传入绘图函数或者使用统一接口设置样式。为了实现统一接口设置，Canvas类必须记录样式状态。

   样式通过样式管理器类完成，其任务是从默认样式文件获取样式，临时储存当前样式，获取当前样式，将当前样式存储为默认样式文件或者样式文件。

   属性，包括不推荐使用的私有属性:

   + `Canvas._curstyle` 当前样式，类型为样式管理器类型
   
   方法:

   + `Canvas.get_style()` 获取当前默认样式
   + `Canvas.set_style(*,fill=None,strick=None,**style_special)` 设置当前默认样式

+ 锚点与命名系统

   pytez支持使用锚点来获取特定点的位置，Canvas类中用字典来储存锚点类。

   所有的支持锚点的类都属于AnchorBase的子类，Anchor是一个简单锚点。

   属性,包括不支持直接调用的私有属性:

   + `Canvas._anchors` 储存所有锚点的字典，默认为空字典。
   + `Canvas.chidren` 只读，储存图形元素和锚点的列表，没有命名的元素也想获取时就需要用到此属性
   
   方法:

   + `Canvas.get_anchors()` 返回锚点命名列表
   + `Canvas.anchor(name,pos)` 设置一个新的指定位置的锚点，类型为Anchor。
   + `Canvas.copy_anchors(element_from,filter=None)` canvas类之间复制锚点
   + `Canvas.get_namedchild(name)` 获取一个命名后的元素，可以是锚点也可以是图形元素

+ 与mpl的交互

   pytez可以视为一个mpl在可视化绘图的延伸设计，只是提供了一个独特的Axes类的包装Canvas类。Canvas类并不具有Axes的属性，相反，Canvas通过ax属性来储存Axes类CanvasAxes。\
   同样CanvasAxes类也可以通过canvas属性获取canvas。

   属性,包括不建议调用的私有属性:

   + `Canvas._ax`
   
   方法: 

   + `Canvas.get_ax()` 

=== 变换矩阵类的设计


在绝对坐标系和相对坐标系中的变换部分，有一定的计算过程，这里将这部分计算过程包含到变换矩阵类 `TransformationMatrix` 。 

=== 图形类的设计


图形类有两种类型，一种是有填充色和线框的2维封闭图形，另一种是只有线型的曲线。填充色属性在曲线中忽略。
2维封闭图形的基础是mpl中的Patch类型，曲线的基础是Line2D类型，因此曲线不仅可以绘制曲线，也可以绘制标记和散点。
图形类也不是artist类，而是artist类型的包装，可以通过 `.artist` 属性调用对应的Artist。

图形类需要解决两个问题，锚点的支持和生成对应的artist类。

+ 锚点

   图形类是锚点类的子类，具体参见锚点类的设计

+ 生成对应的artist类
   
   由于pytez和matplotlib接口的差异性，需要对此进行样式和尺寸的转接，同时还要支持matplotlib对应参数的设计。

+ 支持便捷的定义新的图形类