2008-02-15 | 20:21

点Aから直線に下ろした垂線と直線の交点をPとすると、任意の点Bに対してベクトルPAとベクトルPBの内積の符号は、
点Aと点Bが直線に対して同じ側にあればプラス
点Aと点Bが直線に対して別な側にあればマイナス
となる。
下はこのことを利用したデモ。直線をはさんで赤いボールと同じ側にあるボールは青、反対側にあるボールは緑にしてある。
package { import flash.display.*; import flash.geom.*; import flash.events.*; import flash.utils.*; [SWF(width="500", height="500", framerate="30", backgroundColor="#ffffff")] public class Dot extends Sprite { public var theta:Number = 0; private var balls:Array = []; public function Dot() { for(var i:int = 0 ; i < 150 ; i++){ var b:Ball = new Ball(0xff00, 5); b.x = Math.random()*500; b.y = Math.random()*500; b.vx = Math.random()*3+1; b.vy = Math.random()*3+1; addChild(b); balls.push(b); } balls[0].color = 0xff0000; var t:Timer = new Timer(20); t.addEventListener(TimerEvent.TIMER, loop); t.start(); } private function loop(event:*):void { theta += 0.01; for each (var b:Ball in balls){ b.move(); } // 直線の始点 var lFrom:Point = new Point(250*(1 - Math.cos(theta)), 250*(1 + Math.sin(theta))); // 直線の終点 var lTo:Point = new Point(250*(1 + Math.cos(theta)), 250*(1 - Math.sin(theta))); var len:Number = 500; // 直線の始点と、赤い点を結ぶベクトル var vRed:Point = new Point(balls[0].x - lFrom.x, balls[0].y - lFrom.y); var vLine:Point = new Point(lTo.x - lFrom.x, lTo.y - lFrom.y); // 直線の始点と赤い点を結ぶベクトル と 直線の内積 var dot:Number = vRed.x * vLine.x + vRed.y * vLine.y; // 赤い点から直線におろした垂線と直線との交点 var v:Point = new Point(lFrom.x + (dot/len)*Math.cos(theta), lFrom.y - (dot/len)*Math.sin(theta)); for(var i:int = 1 ; i < balls.length ; i++){ var bdot:Number = (balls[i].x - v.x) * (balls[0].x - v.x) + (balls[i].y - v.y) * (balls[0].y - v.y); if(bdot > 0) balls[i].color = 0xff; else balls[i].color = 0xff00; } graphics.clear(); graphics.beginFill(0xff, 0.2); graphics.lineStyle(2, 0xff, 0.5); graphics.moveTo(lFrom.x, lFrom.y); graphics.lineTo(lTo.x, lTo.y); graphics.endFill(); } } } import flash.display.*; internal class Ball extends Sprite{ public var vx:int = 2; public var vy:int = 2; public var radius:int; public var currentColor:int; public function Ball(c:Number=0, radius:Number = 0){ graphics.lineStyle(1, 0, 0.5); graphics.beginFill(c); graphics.drawCircle(0,0,radius); graphics.endFill(); this.radius = radius; } public function set color(c:int):void{ if(currentColor != c){ currentColor = c; graphics.clear(); graphics.lineStyle(1, 0, 0.5); graphics.beginFill(currentColor); graphics.drawCircle(0,0,radius); graphics.endFill(); } } public function move():void{ x += vx; y += vy; if(x < 0 || x > 500) vx *= -1; if(y < 0 || y > 500) vy *= -1; } }
スポンサーサイト
Comment
Post a comment