`
smallsnake
  • 浏览: 7613 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

折线算法

    博客分类:
  • Flex
 
阅读更多

前提: 

 

 1. 节点具有方向,上/下/左/右 四个方向

 

 2. 节点移动时,必须及时计算出新的方向,

 

先上效果图


 

 

 

package com.donkey.workflow.comp.line
{
	import com.donkey.workflow.comp.Anchor;
	import com.donkey.workflow.comp.OutlineForLine;
	import com.donkey.workflow.event.AnchorDragEvent;
	import com.donkey.workflow.event.NodeDragEvent;
	
	import flash.display.Graphics;
	import flash.geom.Point;

	public class BrokenLine extends Line
	{
		
		private static const FIX_LENGTH:int = 20;
		
		private var _sourceDirection:Number;
		
		private var _targetDirection:Number;
		
		private var _straight:int = 1;
		
		public function BrokenLine()
		{
		}
		
		override protected function createChildren():void
		{
			super.createChildren();
		}
		
		
		override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
		{
			super.updateDisplayList(unscaledWidth, unscaledHeight);
			
			var g:Graphics = graphics;
			g.clear();
			
			var backgroundColor:Number = selected ? getStyle("selectedColor") : getStyle("backgroundColor");
			
			linePoints = [];
			generatePoint(sourcePoint, sourceDirection, targetPoint, targetDirection);
			
			for each (var line:LinePoints in linePoints)
			{
				// 画直线
				g.lineStyle(2, backgroundColor);
				g.moveTo(line.sourcePoint.x, line.sourcePoint.y);
				g.lineTo(line.targetPoint.x, line.targetPoint.y);
			}
			
			var endLine:LinePoints = linePoints[linePoints.length - 1];
			
			if(arrow && null != endLine)
			{
				// 画箭头
				var radius:Number = 8.5;
				var angle:int= GetAngle(endLine.sourcePoint.x, endLine.sourcePoint.y, endLine.targetPoint.x, endLine.targetPoint.y);  
				var centerX:int=endLine.targetPoint.x - radius * Math.cos(angle *(Math.PI/180)) ;  
				var centerY:int=endLine.targetPoint.y + radius * Math.sin(angle *(Math.PI/180)) ;  
				var topX:int=endLine.targetPoint.x;  
				var topY:int=endLine.targetPoint.y;  
				var leftX:int=centerX + radius * Math.cos((angle +120) *(Math.PI/180))  ;  
				var leftY:int=centerY - radius * Math.sin((angle +120) *(Math.PI/180))  ;  
				
				var rightX:int=centerX + radius * Math.cos((angle +240) *(Math.PI/180))  ;  
				var rightY:int=centerY - radius * Math.sin((angle +240) *(Math.PI/180))  ;  
				
				this.graphics.beginFill(backgroundColor, 1);  
				this.graphics.lineStyle(1,backgroundColor, 1);  
				this.graphics.moveTo(topX,topY);  
				this.graphics.lineTo(leftX,leftY);  
				this.graphics.lineTo(centerX,centerY);  
				this.graphics.lineTo(rightX,rightY);  
				this.graphics.lineTo(topX,topY);  
				this.graphics.endFill();
			}
			
			outLine.line = this;
		}
		
		private function GetAngle(startX:Number,startY:Number,endX:Number,endY:Number):int  
		{  
			var tmpx:int=endX - startX ;  
			var tmpy:int=startY -endY ;  
			var angle:int= Math.atan2(tmpy,tmpx)*(180/Math.PI);  
			return angle;  
		}
		
		/**
		 * 生成节点
		 **/
		private function generatePoint(source:Point, sourceD:int, target:Point, targetD:int):void
		{
			smoothPoint(source);
			smoothPoint(target);
			
			var startPoint:Point = offsetPoint(source, sourceD);
			var line:LinePoints = new LinePoints();
			line.sourcePoint = source;
			line.targetPoint = startPoint;
			linePoints.push(line);
			
			var endPoint:Point = offsetPoint(target, targetD);
			
			if (startPoint.y <= endPoint.y)
			{
				this.calculatePoint(startPoint, sourceD, endPoint, targetD);
			}
			else
			{
				this.calculatePoint(endPoint, targetD, startPoint, sourceD);
			}
			
			line = new LinePoints();
			line.sourcePoint = endPoint;
			line.targetPoint = target;
			linePoints.push(line);
		}
		
		/**
		 * 去除误差 
		 * @param source
		 */		
		private function smoothPoint(source:Point):void
		{
			source.x = Math.round(source.x);
			source.y = Math.round(source.y);
			
			if(source.x % 2 == 1)
			{
				source.x = source.x + 1;
			}
			if(source.y % 2 == 1)
			{
				source.y = source.y + 1;
			}
		}
		
		
		/**
		 * 生成开始/结束节点偏移
		 **/
		private function offsetPoint(source:Point, sourceD:int):Point
		{
			var gap:Number;
			var nextSourcePoint:Point = null;
			
			if (Math.abs(sourceD) == 1)
			{
				gap = sourceD > 0 ? FIX_LENGTH : 0 - FIX_LENGTH;
				nextSourcePoint = new Point(source.x + gap, source.y);
			}
			else if (Math.abs(sourceD) == 2)
			{
				gap = sourceD > 0 ? FIX_LENGTH : 0 - FIX_LENGTH;
				nextSourcePoint = new Point(source.x , source.y + gap);
			}
			
			return nextSourcePoint;
		}
		
		/**
		 * 计算
		 **/
		private function calculatePoint(source:Point, sourceD:int, target:Point, targetD:int):void
		{
			if (Math.abs(source.x - target.x) <= 1 && Math.abs(source.y - target.y) <= 1)
			{
				return;
			}
			
			var line:LinePoints = null;
			
			var nextPoint:Point = findNextPoint(source, sourceD, target, targetD);
			
			var nextPointDirection:int = 0;
			if(nextPoint == null)
			{
				nextPoint = new Point(Math.round(source.x + target.x)/2, Math.round(source.y + target.y)/2 );
				if(Math.abs(sourceD) == Math.abs(targetD))
				{
					if(Math.abs(sourceD) == 1)
					{
						nextPointDirection = source.y <= nextPoint.y ? 2 : -2;
					}
					else
					{
						nextPointDirection = source.x <= nextPoint.x ? 1 : -1;
					}
				}
				else
				{
					if(Math.abs(sourceD) == 1)
					{
						nextPointDirection = source.y <= nextPoint.y ? -2 : 2;
					}
					else
					{
						nextPointDirection = source.x <= nextPoint.x ? -1 : 1;
					}
				}
				
				calculatePoint(source, nextPointDirection, nextPoint, sourceD);
				
				calculatePoint(nextPoint, 0 - sourceD, target, targetD);
			}
			else
			{
				// 加入
				line = new LinePoints();
				line.sourcePoint = source;
				line.targetPoint = nextPoint;
				linePoints.push(line);
				
				line = new LinePoints();
				line.sourcePoint = nextPoint;
				line.targetPoint = target;
				linePoints.push(line);
			}
		}
		
		private function findNextPoint(source:Point, sourceD:int, target:Point, targetD:int):Point
		{
			var x:int = 0;
			var y:int = 0;
			
			if(Math.abs(sourceD) == 1)
			{
				if (sourceD > 0)
				{
					if (source.x <= target.x)
					{
						x = target.x;
						y = source.y;
					}
					else if (source.x > target.x)
					{
						x = source.x;
						y = target.y;
					}
				}
				else
				{
					if (source.x <= target.x)
					{
						x = source.x;
						y = target.y;
					}
					else if (source.x > target.x)
					{
						x = target.x;
						y = source.y;
					}
				}
			}
			else
			{
				if (sourceD > 0)
				{
					if (source.y <= target.y)
					{
						x = source.x;
						y = target.y;
					}
					else if (source.y > target.y)
					{
						x = target.x;
						y = source.y;
					}
				}
				else
				{
					if (source.y <= target.y)
					{
						x = target.x;
						y = source.y;
					}
					else if (source.y > target.y)
					{
						x = source.x;
						y = target.y;
					}
				}
			}
			
			var nextPoint:Point = new Point(x, y);
			var directionS:int = calculateDirection(source, nextPoint, sourceD);
			var directionT:int = calculateDirection(nextPoint, target, targetD);
			
			var find:Boolean = false;
			if ((Math.abs(directionS) != Math.abs(sourceD)) || directionS == sourceD)
			{
				//方向相同或者垂直
				if ((Math.abs(directionT) != Math.abs(targetD)) || directionT == 0 - targetD)
				{
					find = true;
				}
				else
				{
					if(directionT == targetD)
					{
						if (Math.abs(targetD) == 1)
						{
							if ((nextPoint.x > target.x && targetD > 0) || (nextPoint.x < target.x && targetD < 0))
							{
								find = true;
							}
						}
					}
				}
			}
			if (find)
			{
				return nextPoint;
			}
			return null;
		}
		
		/**
		 * 计算两个坐标的方向
		 */
		private function calculateDirection(source:Point, target:Point, direction:int):int
		{
			if (source.y == target.y)
			{
				return source.x <= target.x ? 1 : -1;
			}
			else
			{
				return source.y <= target.y ? 2 : -2;
			}
		}

		/**
		 * 根据两个节点之间的位置重新计算开始位置和结束位置
		 **/
		/*override protected function changePoint():void
		{
			if (this.sourceDirection == 1)
			{
				this.sourcePoint.x = this.sourcePoint.x + sourceNode.width / 2;
			}
			if (this.sourceDirection == -1)
			{
				this.sourcePoint.x = this.sourcePoint.x - sourceNode.width / 2;
			}
			
			if (this.sourceDirection == 2)
			{
				this.sourcePoint.y = this.sourcePoint.y + sourceNode.height / 2;
			}
			
			if (this.sourceDirection == -2)
			{
				this.sourcePoint.y = this.sourcePoint.y - sourceNode.height / 2;
			}
			
			// 目标节点
			if (this.targetDirection == 1)
			{
				this.targetPoint.x = this.targetPoint.x + targetNode.width / 2;
			}
			
			if (this.targetDirection == -1)
			{
				this.targetPoint.x = this.targetPoint.x - targetNode.width / 2;
			}
			
			if (this.targetDirection == 2)
			{
				this.targetPoint.y = this.targetPoint.y + targetNode.height / 2;
			}
			
			if (this.targetDirection == -2)
			{
				this.targetPoint.y = this.targetPoint.y - targetNode.height / 2;
			}
		}*/
		
		override protected function changePoint(point:Point, anchor:Anchor):void
		{
			point.x = point.x + anchor.initPoint.x;
			point.y = point.y + anchor.initPoint.y;
		}
		
		override protected function startNodeMoveHandle(event:NodeDragEvent):void{
			updatePoint(sourcePoint, sourceDirection, event, sourceAnchor);
			invalidateDisplayList();
		}
		
		override protected function endNodeMoveHandle(event:NodeDragEvent):void{
			updatePoint(targetPoint, targetDirection, event, targetAnchor);
			invalidateDisplayList();
		}
		
		/**
		 * 更新起始坐标
		 **/
		/*private function updatePoint(point:Point, direction:int, event:NodeDragEvent):void
		{
			if (direction == 1)
			{
				point.x = event.node.x + event.node.width;
				point.y = event.node.y + event.node.height / 2;
			}
			if (direction == -1)
			{
				point.x = event.node.x;
				point.y = event.node.y + event.node.height / 2;
			}
			
			if (direction == 2)
			{
				point.x = event.node.x + event.node.width / 2;;
				point.y = event.node.y + event.node.height;
			}
			
			if (direction == -2)
			{
				point.x = event.node.x + event.node.width / 2;;
				point.y = event.node.y;
			}
		}*/
		
		private function updatePoint(point:Point, direction:int, event:NodeDragEvent, anchor:Anchor):void
		{
			point.x = event.node.x + anchor.initPoint.x;
			point.y = event.node.y + anchor.initPoint.y;
		}
		
		/**
		 * 1. 直线
		 * 2. 曲线
		 * 3. 折线
		 */
		public function get straight():int
		{
			return _straight;
		}
		
		/**
		 * @private
		 */
		public function set straight(value:int):void
		{
			_straight = value;
		}
		
		
		public function get targetDirection():Number
		{
			return _targetDirection;
		}
		
		public function set targetDirection(value:Number):void
		{
			_targetDirection = value;
		}
		
		public function get sourceDirection():Number
		{
			return _sourceDirection;
		}
		
		public function set sourceDirection(value:Number):void
		{
			_sourceDirection = value;
		}

	}
}

 

整体的流程图如下:

 

 


 

  • 大小: 17.4 KB
  • 大小: 26.3 KB
分享到:
评论

相关推荐

    2D 折线顶点平滑算法

    2D 折线顶点平滑算法—— 平滑折线通常可以通过两种方式: 通过插值,即在新的平滑曲线上,原始的折线点仍保持不变; 通过近似,这意味着新的平滑曲线将近似原始的折线,但原始点不会被保留下来。 本代码对两种...

    空间折线外扩算法2.0

    空间折线外扩算法2.0是针对三维空间中线条扩展的一种技术,广泛应用于纹理线绘制和道路生成绘制等场景。这种算法的核心在于能够在保持线条原有形状的基础上,对其边界进行扩展,以创建出具有一定宽度的立体效果。在...

    m基于A律13折线法与μ律15折线的信号压缩MATLAB仿真+word版lun文 +程序操作视频

    1.领域:matlab,A律13折线法与μ律15折线算法 2.内容:m基于A律13折线法与μ律15折线的信号压缩MATLAB仿真+ 本文我们将对A律13折线法与μ律15折线法进行理论研究,然后利用MATLAB实现仿真,对A律13折线法与μ律15...

    GIS中折线平行线坐标的算法与实现

    GIS中折线平行线坐标的算法与实现GIS中折线平行线坐标的算法与实现GIS中折线平行线坐标的算法与实现GIS中折线平行线坐标的算法与实现

    一类有理B_zier曲线的等距线算法及MATLAB实现

    基于Matlab构造B_zier曲线,并绘制等距线

    画贝赛尔曲线算法C++源代码

    贝塞尔曲线是一种在计算机图形学中广泛使用的参数化曲线,特别是在二维图形绘制和动画中。本文将深入探讨贝塞尔曲线的基本概念,以及如何使用C++编程语言实现这种曲线的绘制。 贝塞尔曲线由法国工程师皮埃尔·...

    螺旋矩阵和折线矩阵算法

    螺旋矩阵和折线矩阵是两种在计算机科学中处理二维数组,特别是矩阵时常见的算法。它们在数据结构和算法设计中有着独特的应用,特别是在图形处理、矩阵运算和数据存储等方面。 **螺旋矩阵** 是一种将一个n×n的矩阵...

    大数据-算法-混合折线法和算法TR的线性收.pdf

    本文将对《大数据-算法-混合折线法与算法TR的线性收敛》进行详细介绍,并深入探讨其理论依据和实际应用价值。 论文首先从混合折线法讲起。混合折线法是一种为解决无约束优化问题中的信赖域子问题而提出的新技术。它...

    MFC读入txt画二维折线图和运行算法画折线图和画表格

    在本文中,我们将深入探讨如何使用Microsoft Foundation Class (MFC) 框架在Visual Studio 2012中实现一个应用程序,该程序能够读取TXT文件中的数据绘制二维折线图,同时运行粒子群优化算法(PSO)生成另一组坐标点...

    音视频-编解码-基于投影寻踪和非线性主曲线的高光谱遥感图像特征提取及分类研究.pdf

    为了简化这一非线性投影过程,文章提出了非线性主折线算法,它是对非线性主曲线方法的一种简化实现,不仅易于计算,还能保证分类的准确性。 在所有研究的基础上,本文建立了一种基于非线性主折线的分类算法。该算法...

    数字图像处理软件

    8. **折线算法**:折线算法是用于绘制直线的一种方法,如Bresenham算法,能在离散像素网格上近似地表示出连续的直线。 9. **动态范围压缩**:这是处理图像对比度的一种技术,常用于处理高动态范围图像,将亮度范围...

    Bresenham算法绘制线段并利用“橡皮筋”功能绘制折线

    Bresenham算法是计算机图形学中的一个经典算法,用于高效地在像素网格上近似绘制直线。这个算法由Jack E. Bresenham在1965年提出,主要适用于低分辨率的显示设备,因为它避免了浮点运算,提高了速度。在我们的场景中...

    折线平行线折线平行线.zip

    在C#编程环境中,折线和平行线的绘制是一个常见的图形处理任务,特别是在开发图形用户界面(GUI)或游戏应用时。"折线平行线折线平行线.zip"这个文件可能包含了一个关于如何在C#中实现折线和平行线绘制的教程或代码...

    算法:各种有用的算法和数据结构及其Java实现的集合

    演算法 该存储库是各种有用的算法和数据结构及其Java实现的集合,旨在用于教育用途。 这是一项正在进行的工作,因此可能不包括某些算法。 已添加的所有文件都经过了广泛的测试,应该准确,可读和有效。 随时建议您...

    MATLAB的A律PCM译码器系统仿真.doc.doc

    A律量化通常采用13折线算法,以非线性的方式处理信号,这样可以更有效地编码低电平信号,同时保持高电平信号的精度。 3. **编码**:量化后的电平被转换成对应的二进制码字,通常是8位或16位,以表示不同的量化等级...

    十九届智能车竞赛折线电磁组方案分享.pdf

    ### 十九届智能车竞赛折线电磁组方案解析 #### 一、竞赛背景与赛道特点 全国大学生智能汽车竞赛是一项旨在促进高校学生创新实践能力的科技竞赛活动。本篇文章聚焦于十九届智能车竞赛中的折线电磁组别,对赛道特点...

    人工智能遗传算法实验报告.pdf

    遗传算法实验报告 遗传算法是一种模拟自然进化过程的计算模型,通过模拟生物进化过程搜索最优解。该算法从代表问题可能潜在的解集的一个种群开始,逐代演化产生出越来越好的近似解。在每一代,根据问题域中个体的...

    随机数波形图数据折线图v1.06

    《随机数波形图数据折线图v1.06》是一款基于C++开发的小型应用,主要用于绘制具有随机数生成功能的波形图数据折线图。此工具旨在为用户提供一个直观的方式来可视化和分析随机生成的数据,尤其适用于教学、科研或者...

    FLEX 等距离偏移一条折线

    将一条折线,等距离偏移一定距离。 把屏幕坐标转换为GIS坐标,可以在地图上偏移折线

    矩形裁剪折线 Cohen-Sutherland线裁剪算法

    Cohen-Sutherland线裁剪算法是计算机图形学中一个经典的二维几何裁剪方法,主要用于处理在屏幕坐标系统中,如何将超出可视区域的线条部分剔除,只显示可见部分。这个算法是由Larry G. Cohen和James F. Sutherland在...

Global site tag (gtag.js) - Google Analytics