/// <summary> /// 返回和给定line相等的line的引用 /// </summary> /// <param name="line"></param> /// <returns></returns> public List <PartitionLine> GetLine(PartitionLine line) { List <PartitionLine> resultLines = new List <PartitionLine>(); List <PartitionLine> allLines = new List <PartitionLine>(HPartionLines); allLines.AddRange(VPartionLines); FindLineByLine findByLine = new FindLineByLine(line); PartitionLine includeLine = allLines.Find(findByLine.PredicateIncludeLine); if (includeLine == null) { return(resultLines); } if (line.Start == includeLine.Start && line.End == includeLine.End)///line即为父直线 { resultLines.Add(includeLine); return(resultLines); } if (includeLine.ChildLines != null) { List <PartitionLine> childLines = includeLine.ChildLines.FindAll(findByLine.PredicateIncludedLine); resultLines.AddRange(childLines); } return(resultLines); }
/// <summary> /// 得到已知直线能移动的边界直线 /// </summary> /// <param name="line"></param> /// <returns></returns> internal PartitionLine[] GetLineBorderLine(PartitionLine line) { PartitionLine[] borderLines = new PartitionLine[2]; List <PartitionLine> allLines = new List <PartitionLine>(HPartionLines); allLines.AddRange(VPartionLines); FindLineByLine findByLine = new FindLineByLine(line); List <PartitionLine> resultLines = allLines.FindAll(findByLine.PredicateParallelLine); resultLines.Sort(new CompareLLDistance(line)); int i = 1; for (; i < resultLines.Count; i++) { if ((resultLines[0].Position <line.Position && resultLines[i].Position> line.Position) || (resultLines[0].Position > line.Position && resultLines[i].Position < line.Position)) { break; } } ///左或上的直线放在前面返回 if (resultLines[0].Position < resultLines[i].Position) { borderLines[0] = resultLines[0]; borderLines[1] = resultLines[i]; } else { borderLines[0] = resultLines[i]; borderLines[1] = resultLines[0]; } return(borderLines); }
/// <summary> /// 返回不能被删除之直线 /// </summary> /// <returns></returns> public List <PartitionLine> GetDisDeletableLine() { List <PartitionLine> resultList = new List <PartitionLine>(); List <PartitionLine> selectedLines = GetSelectedLines(); List <PartitionLine> allLines = new List <PartitionLine>(HPartionLines); allLines.AddRange(VPartionLines); FindLineByLine findByLine; foreach (PartitionLine line in selectedLines) { findByLine = new FindLineByLine(line); if (line.IsLocked || allLines.Find(findByLine.PredicateStartEndTo) != null) { resultList.Add(line); } else if (line.ChildLines != null) { foreach (PartitionLine childLine in line.ChildLines) { if (childLine.IsLocked) { resultList.Add(childLine); } } } } return(resultList); }
/// <summary> /// 初始化直线数据:NewLines,EndPointLines,StartPointLines /// </summary> private void InitLines() { ///是否和已有直线重合 PartitionLine line = new PartitionLine( MovedLine.Start, MovedLine.End, MovedToPos, MovedLine.IsRow); FindLineByLine findByLine = new FindLineByLine(line); List <PartitionLine> allLines = new List <PartitionLine>( TDPanel.DrawPanel.ListLine.HPartionLines); allLines.AddRange(TDPanel.DrawPanel.ListLine.VPartionLines); List <PartitionLine> overLapLines = allLines.FindAll(findByLine.PredicateOverlap); List <PartitionLine> resultLines = new List <PartitionLine>(); if (overLapLines.Count > 0) { resultLines = line.GetNotOverlapLine(overLapLines); } else ///没有重合 { resultLines.Add(line); } NewLines = resultLines; ///初始化_endPointLines,_startPointLines FindLineByLine findByMovedLine = new FindLineByLine(MovedLine); EndPointLines = allLines.FindAll(findByMovedLine.PredicateEndTo); StartPointLines = allLines.FindAll(findByMovedLine.PredicateStartFrom); }
/// <summary> /// 得到被选择之直线,并将其拼接成(如果能)一条直线返回,否则返回空 /// </summary> /// <returns>如果能拼接成(如果能)一条直线返回,否则返回空</returns> internal PartitionLine GetSelectedLine() { List <PartitionLine> allLines = new List <PartitionLine>(HPartionLines); allLines.AddRange(VPartionLines); List <PartitionLine> selectedLines = GetSelectedLines(); if (selectedLines.Count < 1) { return(null); } selectedLines.Sort(new CompareLineStart()); PartitionLine selectedLine = new PartitionLine( selectedLines[0].Start, selectedLines[0].End, selectedLines[0].Position, selectedLines[0].IsRow); selectedLine.IsLocked = selectedLines[0].IsLocked; for (int i = 1; i < selectedLines.Count; i++) { if (selectedLines[i].IsRow != selectedLine.IsRow || selectedLines[i].Position != selectedLine.Position || selectedLine.End != selectedLines[i].Start) { return(null); } if (!selectedLines[i].CanMove) { selectedLine.IsLocked = selectedLines[i].IsLocked; } selectedLine.End = selectedLines[i].End; } FindLineByLine findByLine = new FindLineByLine(selectedLine); PartitionLine joinedLine = allLines.Find(findByLine.PredicateJoined); if (joinedLine != null) { return(null); } return(selectedLine); }
///// <summary> ///// 生成div层次关系 ///// </summary> //private void MakeDivLayer() //{ // RectLayer boundaryRect = new RectLayer(0, 0, DrawPanel.Width, DrawPanel.Height,TmpltDoc.TmpltCss); // LineToRect(boundaryRect); // WriteRectLayer(boundaryRect); //} ///// <summary> ///// 将层次化的矩形写入XML,使用树的宽度遍历算法 ///// </summary> ///// <param name="rect"></param> //private void WriteRectLayer(RectLayer rect) //{ // XmlDocument xmlDoc = new XmlDocument(); // string str = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<body></body>"; // xmlDoc.LoadXml(str); // //xmlDoc.Load(@"D:\shiyitang\div.xml"); // XmlElement xmlElement = xmlDoc.DocumentElement; // XmlElement xmlEleTmp = null; // Queue<RectTreeNode> que = new Queue<RectTreeNode>(); // que.Enqueue(new RectTreeNode(rect, xmlElement)); // RectTreeNode curNode = null; // Rect resultRect = null; // while (que.Count > 0) // { // //访问本结点 // curNode = que.Dequeue(); // resultRect = DrawPanel.ListRect.SnipRectList.Find( // new FindRectByLayerRect(curNode.RectLayer).PredicateEqualRect); // if (resultRect != null) // { // curNode.Element.SetAttribute("snippage_id", ((SnipRect)resultRect).SnipID); // } // //如果有孩子,则孩子结点入队 // if (curNode.RectLayer.ChildRects != null) // { // foreach (RectLayer childRect in curNode.RectLayer.ChildRects) // { // xmlEleTmp = xmlDoc.CreateElement("div"); // curNode.Element.AppendChild(xmlEleTmp);//置其为孩子 // que.Enqueue(new RectTreeNode(childRect, xmlEleTmp)); // } // } // } // xmlDoc.Save(@"d:\" + TmpltID + @".xml"); //} /// <summary> /// 递归实现将分割线转化为矩形 /// </summary> /// <param name="snipRect"></param> private void LineToRect(RectLayer snipRect) { if (snipRect == null) { return; } FindLindByRectAndRow findRectPartion; ///寻找能以给定方向(isRow)切割给定矩形之分割线 FindLineByLine findLinePartion; ///寻找能与给定直线正交之分割线 FindLineByLine findLineTo; /// 寻找终点位于给定直线之分割线 List <PartitionLine> resultRectPartion; ///找到与给定方向(isRow)切割给定矩形之分割线的结果集 List <PartitionLine> resultLinePartion; ///找到与给定直线正交之分割线的结果集 RectLayer Rect; ///行优先寻找能横向切割矩形的分割线 findRectPartion = new FindLindByRectAndRow(snipRect, true); resultRectPartion = DrawPanel.HPartionLines.FindAll(new Predicate <PartitionLine>(findRectPartion.Predicate)); if (resultRectPartion.Count > 2)//找到横向切割线,2为两个边界线 { snipRect.IsRow = true; resultRectPartion.Sort(new CompareLinePosition()); if (snipRect.ChildRects == null)//如果还没有new出childRects,则创建 { snipRect.ChildRects = new List <RectLayer>(); } ///循环生成页面矩形 int i; for (i = 1; i < resultRectPartion.Count; i++) { Rect = new RectLayer(snipRect.X, resultRectPartion[i - 1].Position, snipRect.Width, resultRectPartion[i].Position - resultRectPartion[i - 1].Position, ""); snipRect.ChildRects.Add(Rect); LineToRect(Rect); } } else///没有横向切割线,则纵向寻找 { snipRect.IsRow = false; findRectPartion = new FindLindByRectAndRow(snipRect, false); resultRectPartion = DrawPanel.VPartionLines.FindAll(new Predicate <PartitionLine>(findRectPartion.Predicate)); if (resultRectPartion.Count > 2)///找到纵向切割线 { resultRectPartion.Sort(new CompareLinePosition()); if (snipRect.ChildRects == null)///如果还没有new出childRects,则创建 { snipRect.ChildRects = new List <RectLayer>(); } int i = 0, j = 0; while (i < resultRectPartion.Count - 1) { PartitionLine conditionLine = new PartitionLine( snipRect.Y, snipRect.Y + snipRect.Height, resultRectPartion[i].Position, false );///此分割线实质上是此矩的左边界的向右偏移 findLinePartion = new FindLineByLine(conditionLine); resultLinePartion = DrawPanel.HPartionLines.FindAll(new Predicate <PartitionLine>(findLinePartion.PredicatePartedLineRight)); if (resultLinePartion.Count > 0)///找到所有与给定线相交的分割线 { resultLinePartion.Sort(new CompareLineLen(resultRectPartion[i])); findLineTo = new FindLineByLine(resultLinePartion[0]); j = i; i = resultRectPartion.FindLastIndex( new Predicate <PartitionLine>(findLineTo.PredicateLineTo) ); if (i == -1)///如果没有找到,说明此正交分割线没有终止于结果集的任何一条分割线 ///此时,结果应该是最后一条 { i = resultRectPartion.Count - 1; } Rect = new RectLayer( resultRectPartion[j].Position, snipRect.Y, resultRectPartion[i].Position - resultRectPartion[j].Position, snipRect.Height, ""); snipRect.ChildRects.Add(Rect); LineToRect(Rect); } else//没有与之下次之直线,则形成一个新矩形 { j = i; ++i; Rect = new RectLayer( resultRectPartion[j].Position, snipRect.Y, resultRectPartion[i].Position - resultRectPartion[j].Position, snipRect.Height, ""); snipRect.ChildRects.Add(Rect); LineToRect(Rect); } } } } }
public void AddLine(int start, int end, int position, bool isRow) { PartitionLine line = new PartitionLine(start, end, position, isRow); List <PartitionLine> resultLines; ///找到与给定直线正交之分割线的结果集 List <PartitionLine> overLapLine; ///被重叠的直线 ///找到所有被line切割的分割线 FindLineByLine findLinePartion = new FindLineByLine(line); if (line.IsRow) { resultLines = VPartionLines.FindAll(findLinePartion.PredicatePartedLine); if (resultLines.Count >= 1) { ///处理被其切割了其他的直线,同时处理自己也被切割了的情形 for (int i = 0; i < resultLines.Count; i++) { resultLines[i].PartitionByLine(line); line.PartitionByLine(resultLines[i]); } } ///添加新绘之直线,先判断是否有重叠直线 FindLineByLine findByLine = new FindLineByLine(line); overLapLine = HPartionLines.FindAll(findByLine.PredicateOverlap); if (overLapLine.Count == 0) { HPartionLines.Add(line); } else if (overLapLine.Count == 1) { overLapLine[0].MergeOverlapLine(line); } else { PartitionLine removedLine = line.MergeOverlapLine(overLapLine[0], overLapLine[1]); HPartionLines.Remove(removedLine); } } else { resultLines = HPartionLines.FindAll(findLinePartion.PredicatePartedLine); if (resultLines.Count >= 1) { ///处理被其切割了其他的直线,同时处理自己也被切割了的情形 for (int i = 0; i < resultLines.Count; i++) { resultLines[i].PartitionByLine(line); line.PartitionByLine(resultLines[i]); } } ///添加新绘之直线,先判断是否有重叠直线 FindLineByLine findByLine = new FindLineByLine(line); overLapLine = VPartionLines.FindAll(findByLine.PredicateOverlap); if (overLapLine.Count == 0) { VPartionLines.Add(line); } else if (overLapLine.Count == 1) { overLapLine[0].MergeOverlapLine(line); } else { PartitionLine removedLine = line.MergeOverlapLine(overLapLine[0], overLapLine[1]); VPartionLines.Remove(removedLine); } } }
/// <summary> /// 删除直线 /// </summary> /// <param name="line"></param> public void DeleteLine(PartitionLine line) { List <PartitionLine> resultLines; ///找到与给定直线正交之分割线的结果集 ///找到所有被line切割的分割线 FindLineByLine findLinePartion = new FindLineByLine(line); if (line.IsRow)///横向直线 { resultLines = VPartionLines.FindAll(findLinePartion.PredicatePartedLine); if (resultLines.Count >= 1) { for (int i = 0; i < resultLines.Count; i++) { ///合并孩子线段 if (line.FatherLine == null || (line.FatherLine != null && (line.FatherLine.Start == resultLines[i].Position || line.FatherLine.End == resultLines[i].Position) )) { resultLines[i].MergeByPos(line.Position); } } } ///不能简单的HPartionLines.Remove(line),此处只用的为line中的数据,而非引用.因为有可能 ///HPartionLines.Remove(line); FindLineByLine findByLine = new FindLineByLine(line); PartitionLine overLapLine = HPartionLines.Find(findByLine.PredicateIncludeLine); if (overLapLine.Start == line.Start && overLapLine.End == line.End)///如果是同一条线 { HPartionLines.Remove(overLapLine); } else { PartitionLine newLine = overLapLine.RemoveChildLine(line); if (newLine != null)///如果产生了新的线段 { this.HPartionLines.Add(newLine); } if (overLapLine.ChildLines != null && overLapLine.ChildLines.Count == 0) { overLapLine.ChildLines.AddFirst( new LinkedListNode <PartitionLine>( new PartitionLine( overLapLine.Start, overLapLine.End, overLapLine.Position, overLapLine.IsRow))); //line.ChildLines = null; } else if (overLapLine.ChildLines == null) { overLapLine.ChildLines = new SDLinkedList <PartitionLine>(); overLapLine.ChildLines.AddFirst( new LinkedListNode <PartitionLine>( new PartitionLine( overLapLine.Start, overLapLine.End, overLapLine.Position, overLapLine.IsRow))); } } } else///删除纵向切割线 { resultLines = HPartionLines.FindAll(findLinePartion.PredicatePartedLine); if (resultLines.Count >= 1) { for (int i = 0; i < resultLines.Count; i++) { if (line.FatherLine == null || (line.FatherLine != null && (line.FatherLine.Start == resultLines[i].Position || line.FatherLine.End == resultLines[i].Position) )) { ///合并孩子线段 resultLines[i].MergeByPos(line.Position); } } } FindLineByLine findByLine = new FindLineByLine(line); PartitionLine overLapLine = VPartionLines.Find(findByLine.PredicateIncludeLine); if (overLapLine != null) { if (overLapLine.Start == line.Start && overLapLine.End == line.End)///如果是同一条线 { VPartionLines.Remove(overLapLine); } else { PartitionLine newLine = overLapLine.RemoveChildLine(line); if (newLine != null)///如果产生了新的线段 { this.VPartionLines.Add(newLine); } if (overLapLine.ChildLines != null && overLapLine.ChildLines.Count == 0) { overLapLine.ChildLines.AddFirst( new LinkedListNode <PartitionLine>( new PartitionLine( overLapLine.Start, overLapLine.End, overLapLine.Position, overLapLine.IsRow))); //line.ChildLines = null; } else if (overLapLine.ChildLines == null) { overLapLine.ChildLines = new SDLinkedList <PartitionLine>(); overLapLine.ChildLines.AddFirst( new LinkedListNode <PartitionLine>( new PartitionLine( overLapLine.Start, overLapLine.End, overLapLine.Position, overLapLine.IsRow))); } } } } }