球与直线的碰撞检测及反应 |
| 作者:佚名 来源:zjs35blog 作者: zjs35 更新:2007-1-13 20:46:05 错误报告 我要投稿 |
|
昨晚写的点类和直线类,并做了两个测试,效果在后面
/** * 绘制实点类 * * @作者 章精设(zjs35) * @版本 v1 */ class game.Point { private var _x:Number; private var _y:Number; public function Point(x:Number, y:Number) { this._x = x; this._y = y; } public function toString() { trace([_x, _y]); } public function get x() { return _x; } public function set x(x:Number):Void { this._x = x; } public function get y() { return _y; } public function set y(y:Number):Void { this._y = y; } public function reset(x, y) { this._x = x; this._y = y; } public function setPosition(mc) { mc._x = _x; mc._y = _y; } public static function distance(p1:Point, p2:Point) { var dx = p2.x-p1.x; var dy = p2.y-p1.y; return Math.sqrt(dx*dx+dy*dy); } }
/** * 绘制实直线类 * * @作者 章精设(zjs35) * @版本 v1 */ import game.Point; import fc.graphics.*; import fc.graphics.draw2d.GDI; //两点式直线类 class game.Line { //决定直线的两点 private var _p1:Point; private var _p2:Point; private var _GDI:GDI; //构造函数 public function Line(p1:Point, p2:Point) { _p1 = p1; _p2 = p2; } public function toString():String { return "instance of Line Class "; } //返回第一个点 public function get p1():Point { return _p1; } //返回第二个点 public function get p2():Point { return _p2; } //重新设置两点 public function reset(p1:Point, p2:Point):Void { _p1 = p1; _p2 = p2; } //返回中点 public function midPoint():Point { return new Point((_p1.x+_p2.x)/2, (_p1.y+_p2.y)/2); } //求直线的倾斜角,以角度表示 public function angle():Number { return fc.math.Degree.atan2D(_p2.y-_p1.y, _p2.x-_p1.x); } //求直线的斜率 public function slope():Number { if (_p1.x == _p2.x) { return undefined; } return (_p2.y-_p1.y)/(_p2.x-_p1.x); } //绘制直线 public function draw(mc, pen:Pen):Void { _GDI = GDI.getInstance(); _GDI.target = mc; //t.clear(); _GDI.line(pen, new fc.graphics.draw2d.Line(_p1.x, _p1.y, _p2.x, _p2.y)); } public function clear(mc):Void { _GDI.target = mc; _GDI.clear(); } //定比 public function ratio(r) { } //点是否在直线上(两点之间) public function dotOfLine(p:Point):Boolean { var d1 = Point.distance(p, _p1); var d2 = Point.distance(p, _p2); var d3 = Point.distance(_p1, _p2); //0.01用于避免浮点数 return d1+d2-d3<0.01; } //点到直线的距离 public function dotToLine(p:Point):Number { var l:Line = this.uprightness(p); var point:Point = this.pointOfIntersection(l); //有交点时返回距离 if (point != undefined) { return Point.distance(point, p); } } //求过点p的垂线 public function uprightness(p:Point):Line { var k = this.slope(); //没考虑k=0的情况 var t1:Point = new Point(0, p.y+1/k*p.x); var t2:Point = new Point(k*p.y+p.x, 0); if (k == 0) { var t1:Point = new Point(p.x, 0); var t2:Point = new Point(p.x, Stage.height); } else if (k == undefined) { var t1:Point = new Point(0, p.y); var t2:Point = new Point(Stage.width, p.y); } return new Line(t1, t2); } //两直线的交点 public function pointOfIntersection(line:Line):Point { //直线1的参数 var t1 = this.transCommon(); var a1 = t1.a; var b1 = t1.b; var c1 = t1.c; //直线2的参数 var t2 = line.transCommon(); var a2 = t2.a; var b2 = t2.b; var c2 = t2.c; //计算交点 var p = new Point((c2*b1-c1*b2)/(a1*b2-a2*b1), (a1*c2-a2*c1)/(a2*b1-a1*b2)); //交点在两点直线的两点之间 if (this.dotOfLine(p) && line.dotOfLine(p)) { return p; } } //直线的位置关系,true示平行,false示相交 public function position(l:Line) { return this.slope() == l.slope(); } //直线方程的形式转换:两点式转换为一般式 public function transCommon():Object { var k = this.slope(); var t1, t2, t3; if (k == undefined) { t1 = 1; t2 = 0; t3 = -_p1.x; } else { t1 = -k; t2 = 1; t3 = k*_p1.x-_p1.y; } return {a:t1, b:t2, c:t3}; } //两直线所成的角 }
效果1,还有bug
效果2,用左右方向键控制
其实可点与直线的检测开始,效果图 1两直线的交点,如果交点在直线外,不检测
2点到直线的距离,同样,垂足在直线外也不计算
主要是凹多边形和凸多边形的检测 效果1
效果2,凹点碰撞有问题,现在只有比较笨的解决办法,大家帮偶想想
|
|
| 文章录入:skyuu 责任编辑:skyuu |
|
| 【字体:小 大】【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口】 |