flash:二次贝塞尔曲线应用-生成飞机路径示意图

本周听到公司其它项目组同事在讨论一个小需求:

给定3个点(其实是飞机经过的航站,比如:从浦东-西安-北京),在UI上生成一段曲线,用来示意飞机的路线图(其实用直线我觉得也能将就,反正只是示意,只是大家觉得直线太out,不美观),晚上无事,尝试了一下:
有二个方案:
1、椭圆(很快被自己给否定了,椭圆的标准方程 (x-m)^2/(a^2) + (y-n)^2/(b^2)=1,有m,n,a,b 四个未知数,3个点无法唯一确定,如果把圆心定在页面中心,理论上可以解决,但是开平方也是比较繁琐的)
2、贝塞尔曲线

根据:(贝塞尔曲线)喂鸡百科的解释:
二次标准方程为:

正好以前在学习flash时也研究过,所以决定用它了。解决了曲线的生成问题,还有飞机的朝向问题,飞机头是有方向的,必须符合曲线的前进方向,这个可用“曲线导数的几何意义”搞定:曲线某点的导数,正好为该点切线的斜率(换个角度考虑,其实就是飞机图标的旋转角度)

捣鼓一阵后,代码出来了:

先定义一个飞机的实体类(为方便,暂时用小三角形代替)

package
{
	import flash.display.Shape;
	/**
	 * 飞机实体类
	 * @author jimmy.yang
	 */
	public class Plane extends Shape
	{

		public function Plane()
		{
			//用一个小三角来模拟飞机
			graphics.lineStyle(1, 0xff0000, 1);
			graphics.beginFill(0xff0000, 1);
			graphics.moveTo( -50, -25);
			graphics.lineTo(50, 0);
			graphics.lineTo( -50, 25);
			graphics.lineTo( -50, -25);
			graphics.endFill();
		}

		public function setAngle(y:Number,x:Number) {
			this.rotation = Math.atan2(y,x) * 180 / Math.PI;
		}

	}

}

 下面是生成曲线及调整飞机头朝向的代码:

package
{
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.text.TextField;

	/**
	 * 二次贝兹曲线,生成飞机路线图
	 * @author jimmy.yang (yjmyzz@126.com 菩提树下的杨过 http://yjmyzz.cnblogs.com/)
	 */
	[Frame(factoryClass="Preloader")]
	public class Main extends Sprite
	{		

		public function Main():void
		{
			if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, init);
		}

		private function init(e:Event = null):void
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);
			testBzCurve();
		}

		private function testBzCurve():void {

			var txtP0:TextField = new TextField();
			var txtP1:TextField = new TextField();
			var txtP3:TextField = new TextField();
			addChild(txtP0);
			addChild(txtP1);
			addChild(txtP3);

			var p0X:int = 100;
			var p0Y:int = 300;

			txtP0.x = p0X-10;
			txtP0.y = p0Y+10;
			txtP0.text = "浦东(PVG)";

			var p1X:int = 300;
			var p1Y:int = 250;
			txtP1.x = p1X;
			txtP1.y = p1Y+20;
			txtP1.text = "西安(XIY)";

			var p2X:int = 500;
			var p2Y:int = 50;
			txtP3.x = p2X+5;
			txtP3.y = p2Y;
			txtP3.text = "北京(PEK)";

			//人为抬高控制点,以便让曲线经过控制点
			p1X = p1X * 2 - (p0X + p2X) / 2;
			p1Y = p1Y * 2 - (p1Y + p2Y) / 2;

			//生成10个示例点
			for (var t:Number = 0; t <=1; t+=0.1)
			{
				//二次Bz曲线的公式
				var x:Number = (1 - t) * (1 - t) * p0X + 2 * t * (1 - t) * p1X + t * t * p2X;
				var y:Number = (1 - t) * (1 - t) * p0Y + 2 * t * (1 - t) * p1Y + t * t * p2Y;				

				//Bz曲线在t点时的导数坐标
				var Fx:Number = 2 * (t - 1) * p0X + 2 * (1 - 2 * t) * p1X + 2 * t * p2X;
				var Fy:Number = 2 * (t - 1) * p0Y + 2 * (1 - 2 * t) * p1Y + 2 * t * t * p2Y;

				//放入小飞机
				var p = new Plane();
				addChild(p);
				p.x = x;
				p.y = y;
				p.scaleX = 0.2;
				p.scaleY = 0.2;
				p.setAngle(Fy, Fx);//导数的几何意义

			}

			//画出Bz曲线(当背景用)
			graphics.lineStyle(1, 0x000000, 0.5);
			graphics.moveTo(p0X, p0Y);
			graphics.curveTo(p1X, p1Y, p2X, p2Y);

		}

	}

}

 无图无真相:

感慨:数学真心有用!

 

时间: 2024-10-12 07:25:31

flash:二次贝塞尔曲线应用-生成飞机路径示意图的相关文章

HTML5 Canvas中使用路径描画二阶、三阶贝塞尔曲线

  在HTML5 Canvas中,可以用以下方法描画三阶和二阶的贝塞尔曲线: 代码如下: context.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y) context.quadraticCurveTo(cpx, cpy, x, y) 贝塞尔曲线是在二维平面上由一个"起始点",一个"结束点",以及一个或多个"控制点"定义的曲线.普通的三阶贝塞尔曲线使用两个控制点,而二阶曲线则只使用一个控制点. 要描画二阶贝

「玩一玩」贝塞尔曲线,以及用鼠标和贝塞尔曲线交互

问题描述 by野比喵这段时间感觉很蛋疼..虽然各种游戏玩的很开心..还是多少要学习一下呗..做了个小东西,贴出来得瑟下..能力有限,就先这么着了.别试图找我要任何代码之类的..我只是个amateur,这种帖子认真你就输了..别试图接分..那是不可能的..当你对生活不满意,工作不满意,妹妹不满意...如果不想付出金钱去改变,活该苦逼.如果不想付出精力去改变,活该苦逼.如果不想付出生命去改变,活该苦逼.如果不能忍受别人的鄙视,亲,请给别人一个不鄙视你的理由先..其实这篇没什么技术含量,类似Photo

使用canvas绘制贝塞尔曲线

 1.二次贝塞尔曲线 quadraticCurveTo(cpx,cpy,x,y) //cpx,cpy表示控制点的坐标,x,y表示终点坐标: 数学公式表示如下: 二次方贝兹曲线的路径由给定点P0.P1.P2的函数B(t)追踪: 代码实例:   代码如下: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>canvas直线</title> <m

canvas绘制贝塞尔曲线

原文:canvas绘制贝塞尔曲线 1.绘制二次方贝塞尔曲线 quadraticCurveTo(cp1x,cp1y,x,y); 其中参数cp1x和cp1y是控制点的坐标,x和y是终点坐标 数学公式表示如下: 二次方贝兹曲线的路径由给定点P0.P1.P2的函数B(t)追踪: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <

Android把商品添加到购物车的动画效果(贝塞尔曲线)_Android

当我们写商城类的项目的时候,一般都会有加入购物车的功能,加入购物车的时候会有一些抛物线动画,具体代码如下: 实现效果如图: 思路: 确定动画的起终点 在起终点之间使用二次贝塞尔曲线填充起终点之间的点的轨迹 设置属性动画,ValueAnimator插值器,获取中间点的坐标 将执行动画的控件的x.y坐标设为上面得到的中间点坐标 开启属性动画 当动画结束时的操作 难点: PathMeasure的使用 - getLength() - boolean getPosTan(float distance, f

Android Path绘制贝塞尔曲线实现QQ拖拽泡泡_Android

这两天学习了使用Path绘制贝塞尔曲线相关,然后自己动手做了一个类似QQ未读消息可拖拽的小气泡,效果图如下: 最终效果图 接下来一步一步的实现整个过程. 基本原理 其实就是使用Path绘制三点的二次方贝塞尔曲线来完成那个妖娆的曲线的.然后根据触摸点不断绘制对应的圆形,根据距离的改变改变原始固定圆形的半径大小.最后就是松手后返回或者爆裂的实现. Path介绍: 顾名思义,就是一个路径的意思,Path里面有很多的方法,本次设计主要用到的相关方法有 moveTo() 移动Path到一个指定的点 qua

IOS 贝塞尔曲线(UIBezierPath)属性、方法整理_IOS

IOS 贝塞尔曲线详解         开发IOS的朋友都知道IOS 贝塞尔曲线的重要性,由于经常会用到这样的东西,索性抽时间就把相应所有的属性,方法做一个总结. UIBezierPath主要用来绘制矢量图形,它是基于Core Graphics对CGPathRef数据类型和path绘图属性的一个封装,所以是需要图形上下文的(CGContextRef),所以一般UIBezierPath在drawRect中使用. UIBezierPath的属性介绍: 1.CGPath:将UIBezierPath类转

iOS - Quartz 2D 贝塞尔曲线

1.贝塞尔曲线 贝塞尔曲线(Bézier curve),又称贝兹曲线或贝济埃曲线,是应用于二维图形应用程序的数学曲线.一般的矢量图形软件通过它来精确画出曲线,贝兹曲线由线段与节点组成,节点是可拖动的支点,线段像可伸缩的皮筋,我们在绘图工具上看到的钢笔工具就是来做这种矢量曲线的.贝塞尔曲线是计算机图形学中相当重要的参数曲线,在一些比较成熟的位图软件中也有贝塞尔曲线工具,如 PhotoShop 等.在 Flash4 中还没有完整的曲线工具,而在 Flash5 里面已经提供出贝塞尔曲线工具. 二阶贝塞

算法研究之贝塞尔曲线

贝塞尔曲线 贝塞尔曲线(The Bézier Curves),是一种在计算机图形学中相当重要的参数曲线(2D,3D的称为曲面).贝塞尔曲线于1962年,由法国工程师皮埃尔·贝塞尔(Pierre Bézier)所发表,他运用贝塞尔曲线来为汽车的主体进行设计. 线性曲线 给定点P0.P1,线性贝塞尔曲线只是一条两点之间的直线.这条线由下式给出: 当参数t变化时,其过程如下: 线性贝塞尔曲线函数中的t会经过由P0至P1的B(t)所描述的曲线.例如当t=0.25时,B(t)即一条由点P0至P1路径的四分