M | 邏輯座標系,系統座標系 |
V | 顯示座標系,視圖座標系,用戶座標系,用戶屏幕 |
C | 用戶控制器,操縱桿 |
1 public enum LineType 2 { 3 // 4 // 摘要: 5 // 直線 6 Straight = 0, 7 // 8 // 摘要: 9 // 射線 10 Ray = 1, 11 // 12 // 摘要: 13 // 線段 14 Line = 2 15 }
可是兩點的定義方式並不夠,(p1是第一個點,p2是第二個點),若是用戶是過線(含延長線)和一點作的垂線,這個邏輯也須要體現,canvas
因此咱們須要一個LineRely來記錄線的構造(生成)方式設計模式
1 public enum LineRely 2 { 3 // 4 // 摘要: 5 // 常規方式,p1,p2兩點肯定一條直線 6 Normal = 0, 7 // 8 // 摘要: 9 // 垂線,依賴列表的一條線加上線上或者線外點p1,過p1做依賴點的垂線 10 Perpendicular = 1, 11 // 12 // 摘要: 13 // 垂直平分線,p1,p2兩點連線的中垂線 14 PerpendicularBisector = 2, 15 // 16 // 摘要: 17 // 垂直平分線,p1,p2兩點連線的中垂線 18 AngleBisector = 3, 19 }
與構造方式LineRely配套的須要一些屬性(字段),好比垂線構造(三個點,一點一線),中垂線構造(兩個點,一個線段),角平分線構造(三個點,兩條射線)等方式ide
4,圓的構造就容易不少模塊化
兩個點,一個是圓心,另外一個是圓上的一點函數
(爲何不用半徑,由於用戶依靠鼠標的點擊生成圓周上的點,並且這個點是圓的重要的控制點,因此後續半徑須要計算生成)工具
視圖座標系中的元素:spa
一條邏輯線在一個座標系中有幾個像?是一個嗎?不是。操作系統
在這個引擎中,視圖座標系中的元素是能夠直接顯示的,若是你畫的線是一個線段(或者是一條射線),一條邏輯線就會有兩個視圖線,一條實線,一條虛線,先畫虛線(延長線),在畫實線。設計
視圖座標系中的元素都是幾何體嗎?不是。(註釋和標籤,待實現)3d
視圖座標系中能夠放置OutputText
1 /// <summary> 2 /// 屏幕上的提示文本,或者是屏幕上元素的「名字標籤」 3 /// </summary> 4 public class OutputText : ICanOutput 5 { 6 /// <summary> 7 /// 文本內容 8 /// </summary> 9 public string text { get; set; } 10 11 /// <summary> 12 /// 在屏幕上的窗體(canva)中,這個文本「寫」在哪裏 13 /// </summary> 14 public Vector2 viewPoint { get; set; } 15 16 /// <summary> 17 /// 文字顏色 18 /// </summary> 19 public Color fontColor { get; set; } 20 21 /// <summary> 22 /// 文字格式 23 /// </summary> 24 public CanvasTextFormat format { get; set; } 25 26 /// <summary> 27 /// 這個文字是不是某個幾何體的標籤(名字) 28 /// </summary> 29 public Models.Geometry.Geometry rely { get; set; } 30 }
文本沒有」原像」(借用數學中函數的概念),可是有依賴,好比這個文本是一個點的標籤,依賴保證了文本的座標始終圍繞在這個點必定範圍周邊,不能被拖動太遠
1 // <summary> 2 /// 邏輯座標系到屏幕顯示座標系的轉換(左上角模式) 3 /// </summary> 4 /// <param name="p2"></param> 5 /// <returns>v2</returns> 6 public Vector2 ToVector2Upper_Left_Corner(Point2 p2) 7 { 8 float x = p2.X - vector.X; 9 float y = p2.Y - vector.Y; 10 x = x / unitLength; 11 y = -y / unitLength; 12 Vector2 v2 = new Vector2(x,y); 13 return v2; 14 } 15 /// <summary> 16 /// 屏幕顯示座標系到邏輯座標的轉換(左上角模式) 17 /// </summary> 18 /// <param name="v2"></param> 19 /// <returns>Point2 p2</returns> 20 public Point2 ToPoint2Upper_Left_Corner(Vector2 v2) 21 { 22 Point2 p2 = new Point2() { X = (v2.X*unitLength+vector.X), Y = -(v2.Y*unitLength+vector.Y) }; 23 return p2; 24 }
1 /// <summary> 2 /// 邏輯座標系到屏幕顯示座標系的轉換(中心模式) 3 /// </summary> 4 /// <param name="p2"></param> 5 /// <returns>屏幕上的點</returns> 6 public Vector2 ToVector2(Point2 p2) 7 { 8 Vector2 vop = new Vector2() { X = p2.X - vector.X, Y = vector.Y - p2.Y }; 9 //if (WindowHeight <= 0 || WindowWidth <= 0) throw new Exception("中心構造方式須要瞭解canvas畫布的actual寬和高"); 10 Vector2 half = new Vector2() { X = WindowWidth / 2, Y = WindowHeight / 2 }; 11 Vector2 result = half + vop * unitLength; 12 return result; 13 } 14 /// <summary> 15 /// 屏幕顯示座標系到邏輯座標的轉換(中心模式) 16 /// </summary> 17 /// <param name="v2"></param> 18 /// <returns>邏輯座標系中的點</returns> 19 public Point2 ToPoint2(Vector2 v2) 20 { 21 if (WindowHeight <= 0 || WindowWidth <= 0) throw new Exception("中心構造方式須要瞭解canvas畫布的actual寬和高"); 22 Vector2 half = new Vector2() { X = WindowWidth / 2, Y = WindowHeight / 2 }; 23 Vector2 vop = (v2 - half) / unitLength; 24 Point2 p2 = new Point2() { X = (vop.X + vector.X), Y = -vop.Y + vector.Y }; 25 return p2; 26 }