In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

Draw curve with hint

点と点を曲線で繋ぐ(こんなふうに描きました)
* Please drag red Circle and confirm the change.
Get Adobe Flash player
by Kay 17 Mar 2009
// forked from Kay's Draw curve
/*
 * 点と点を曲線で繋ぐ(こんなふうに描きました)
 * Please drag red Circle and confirm the change.
 */
package {
	import flash.display.Sprite;
	import flash.display.Shape;
	import flash.geom.Point;
	[SWF(width=465, height=465, backgroundColor=0x000000, frameRate=30)]
	public class Take03 extends Sprite {
		private const PNUM:uint = 12;
		private const ANGLE:Number = 360/PNUM;
		private const RADIUS:uint = 150;
		private const SW:uint = stage.stageWidth;
		private const SH:uint = stage.stageHeight;
		private var points:Vector.<Sprite> = new Vector.<Sprite>();
		private var controlStage:Sprite;
		private var hintLineStage:Shape;
		private var hintPointStage:Shape;
		private var drawStage:Shape;
		public function Take03():void {
			controlStage = new Sprite();
			for (var i:uint = 0; i < PNUM; i++) {
				var cp:ControlPoint = new ControlPoint();
				var myP:Point = Point.polar(RADIUS,ANGLE*i/180*Math.PI);
				myP.offset(SW/2,SH/2);
				cp.x = myP.x;
				cp.y = myP.y;
				controlStage.addChild(cp);
				points.push(cp);
			}
			hintLineStage = new Shape();
			hintPointStage = new Shape();
			drawStage = new Shape();
			drawLine();
			addChild(drawStage);
			addChild(hintLineStage);
			addChild(hintPointStage);
			addChild(controlStage);
		}
		public function drawLine():void {
			drawStage.graphics.clear();
			drawStage.graphics.lineStyle(5,0xffffff);
			drawStage.graphics.moveTo(points[1].x,points[1].y);
			hintLineStage.graphics.clear();
			hintLineStage.graphics.lineStyle(0,0x00ffff);
			hintLineStage.graphics.moveTo(points[1].x,points[1].y);
			hintPointStage.graphics.clear();
			for (var i:uint = 0; i < PNUM; i++) {
				var pA:uint = (i+PNUM)%PNUM;
				var pB:uint = (pA+1)%PNUM;
				var pC:uint = (pB+1)%PNUM;
				var pD:uint = (pC+1)%PNUM;
				var cp:Array = getCurvePoint(points[pA],points[pB],points[pC],points[pD]);
				drawStage.graphics.curveTo(cp[0].x,cp[0].y,cp[1].x,cp[1].y);
				drawStage.graphics.curveTo(cp[2].x,cp[2].y,points[pC].x,points[pC].y);
				hintLineStage.graphics.lineTo(cp[0].x, cp[0].y);
				hintLineStage.graphics.lineTo(cp[1].x, cp[1].y);
				hintLineStage.graphics.lineTo(cp[2].x, cp[2].y);
				hintLineStage.graphics.lineTo(points[pC].x, points[pC].y);
				hintPointStage.graphics.beginFill(0xff00ff);
				hintPointStage.graphics.drawCircle(cp[0].x,cp[0].y,2);
				for (var j:uint = 0; j < 3; j++) {
					hintPointStage.graphics.endFill();
					hintPointStage.graphics.beginFill(0xff00ff);
					hintPointStage.graphics.drawCircle(cp[j].x,cp[j].y,2.5);
				}
			}
		}
		// 与えられた4点からその中間2点(A0,B0)を曲線で繋ぐための位置(controlPointA,mp,controlPointB)を求める
		private function getCurvePoint(a:Sprite, b:Sprite, c:Sprite, d:Sprite):Array {
			// Point targetA,targetBの距離
			var beforeA:Point = new Point(a.x, a.y);
			var targetA:Point = new Point(b.x, b.y);
			var targetB:Point = new Point(c.x, c.y);
			var afterB :Point = new Point(d.x, d.y);
			var connectL:Number = Point.distance(targetA,targetB);
			//var connectR:Number = getRadian(targetB,targetA);
			// コントロールポイント(controlPoint)の要素
			var controlPointA:Object = new Object();
			controlPointA.r = getRadian(targetB, beforeA);
			controlPointA.p = Point.distance(targetA, beforeA);	// この線にかかる力(接続線の距離)
			var controlPointB:Object = new Object();
			controlPointB.r = getRadian(targetA, afterB);
			controlPointB.p = Point.distance(targetB, afterB);	// この線にかかる力(接続線の距離)
			// 力のかかる比率 
			var ratio:Number = controlPointA.p/(controlPointA.p+controlPointB.p);
			// コントロールポイント(controlPoint)の位置を求める
			if (targetA.equals(beforeA)) {
				controlPointA.x = beforeA.x;
				controlPointA.y = beforeA.y;
			} else {
				controlPointA.l = connectL/2*ratio;	//*Math.tan(getRadianDiff(connectR,controlPointA.r));
				controlPointA.x = targetA.x + controlPointA.l*Math.cos(controlPointA.r);
				controlPointA.y = targetA.y + controlPointA.l*Math.sin(controlPointA.r);
			}
			if (targetB.equals(afterB)) {
				controlPointB.x = afterB.x;
				controlPointB.y = afterB.y;
			} else {
				controlPointB.l = connectL/2*(1-ratio);	//*Math.tan(getRadianDiff(controlPointB.r,connectR));
				controlPointB.x = targetB.x + controlPointB.l*Math.cos(controlPointB.r);
				controlPointB.y = targetB.y + controlPointB.l*Math.sin(controlPointB.r);
			}
			// 中間点(centerPoint)
			var centerPoint:Point = new Point();
			centerPoint.x = controlPointA.x + (controlPointB.x-controlPointA.x)*ratio;
			centerPoint.y = controlPointA.y + (controlPointB.y-controlPointA.y)*ratio;
			// 中間点と2つのコントロールポイントとを返す
			return ([controlPointA,centerPoint,controlPointB]);	
		}
		private function getRadian(a:Point,b:Point):Number {
			var dx:Number = (a.x - b.x);
			var dy:Number = (a.y - b.y);
			var radian:Number = Math.atan2(dy,dx);
			return (radian);
		}
	}
}
import flash.display.Sprite;
import flash.display.Shape;
import flash.events.MouseEvent;
import flash.events.Event;
class ControlPoint extends Sprite {
	private var dFlag:Boolean = false;
	public function ControlPoint():void {
		graphics.beginFill(0xff0000);
		graphics.drawCircle(0,0,10);
		graphics.endFill();
		addEventListener(MouseEvent.MOUSE_DOWN, beginDrag);
		addEventListener(MouseEvent.MOUSE_UP, finishDrag);
		addEventListener(MouseEvent.MOUSE_MOVE, movePoint);
		buttonMode = true;
	}
	private function movePoint(e:Event):void {
		if (dFlag) e.target.parent.parent.drawLine();
	}
	private function beginDrag(e:MouseEvent):void {
		dFlag = true;
		this.startDrag();
	}
	private function finishDrag(e:MouseEvent):void {
		dFlag = false;
		this.stopDrag();
	}
}