問題: 當選中多個幾何對象, 使用鼠標移動, 則如何移動, 以保證正確的幾何約束關係, 以及
令人"看起來"此移動比較"正常,合理"? 算法
設被選中的對象的集合爲S, 先構造一個集合M, 移動S被轉換爲等價於移動集合M, 且集合M
中的對象都是自由度非0(可自主=2或半自主=1移動的)的對象. 數組
當前有徹底移動自由度的對象主要是自由點. 也有FixedText,Button的特殊對象, 但它們一般不
具備幾何約束關係, 故而在研究移動的時候能夠略. 自由點對象能夠在 x,y 兩個方向任意移動,
其影響別的幾何對象, 且不被別的任何幾何對象影響. 對象
有半移動自由度的對象是對象上的點(Point On Object). 它們有在對象路徑(path)上的 t 方向
的一個自由度. 若是這次移動操做不影響該類點的父對象, 則該點能夠看作是自由點移動. map
從 S 構造 M 的算法以下:
1. 設置 M 的初值 = S (複製一份); 在實際中, S 是數組, M 是以對象 id 爲 key 的 map.
2. 構造 M 的全部子孫節點的集合 C, C 包含 M 及 M 的全部子孫對象.
3. 掃描 M 集合的每一個對象 obj, 若是該對象的自由度 = 0, 則從 M 中移除該 obj, 加入 該
obj 的移動控制對象 (move_ctrl()), 其通常是但不絕對是父對象集合. 同時更新 C.
4. 重複步驟 3, 直到集合 M 再也不發生變化. 此時 M 是最終的移動控制集合. 方法
經過移動集合 M 中的對象, 這些對象相互之間的移動是獨立的, 能夠"分別"移動. 移動發生以後
更新集合 C 中全部受影響對象, 便可完成移動操做. 數據
爲實現移動操做的 Undo/Redo , 須要給對象的位置信息(可能在移動的每個時刻)都創建
一個快照(snapshot), 一個 undo 操做等價於將位置信息恢復到開始點的位置快照, 一個 redo
操做等價於將位置信息設置到結束點的位置快照. 集合
位置快照使用的數據的邏輯結構是 M: { id: pos-snapshot }, 其中每一個 pos-snapshot 可約定簡化
爲一個數字的 array, 如 [x, y], 或 [t]. 可使用壓縮的表示方法, 如 3,x,y|4,t|9,x,y ...
因爲集合 C 能夠經過 M 構造出來, 因此可不被保存到快照中, 而是每次 undo/redo 操做時構造. 移動