修复RealtimeCollisions.intersectMovingCircleBox计算问题
This commit is contained in:
10
source/bin/framework.d.ts
vendored
10
source/bin/framework.d.ts
vendored
@@ -1638,10 +1638,12 @@ declare class TimeUtils {
|
|||||||
static timeToMillisecond(time: string, partition?: string): string;
|
static timeToMillisecond(time: string, partition?: string): string;
|
||||||
}
|
}
|
||||||
declare module es {
|
declare module es {
|
||||||
/** 贝塞尔帮助类 */
|
/**
|
||||||
|
* 三次方和二次方贝塞尔帮助器(cubic and quadratic bezier helper)
|
||||||
|
*/
|
||||||
class Bezier {
|
class Bezier {
|
||||||
/**
|
/**
|
||||||
* 二次贝塞尔曲线
|
* 求解二次曲折线
|
||||||
* @param p0
|
* @param p0
|
||||||
* @param p1
|
* @param p1
|
||||||
* @param p2
|
* @param p2
|
||||||
@@ -2370,8 +2372,8 @@ declare module es {
|
|||||||
bottomRight = 6
|
bottomRight = 6
|
||||||
}
|
}
|
||||||
class Collisions {
|
class Collisions {
|
||||||
static isLineToLine(a1: Vector2, a2: Vector2, b1: Vector2, b2: Vector2): boolean;
|
static lineToLine(a1: Vector2, a2: Vector2, b1: Vector2, b2: Vector2): boolean;
|
||||||
static lineToLineIntersection(a1: Vector2, a2: Vector2, b1: Vector2, b2: Vector2): Vector2;
|
static lineToLineIntersection(a1: Vector2, a2: Vector2, b1: Vector2, b2: Vector2, intersection?: Vector2): boolean;
|
||||||
static closestPointOnLine(lineA: Vector2, lineB: Vector2, closestTo: Vector2): Vector2;
|
static closestPointOnLine(lineA: Vector2, lineB: Vector2, closestTo: Vector2): Vector2;
|
||||||
static circleToCircle(circleCenter1: Vector2, circleRadius1: number, circleCenter2: Vector2, circleRadius2: number): boolean;
|
static circleToCircle(circleCenter1: Vector2, circleRadius1: number, circleCenter2: Vector2, circleRadius2: number): boolean;
|
||||||
static circleToLine(circleCenter: Vector2, radius: number, lineFrom: Vector2, lineTo: Vector2): boolean;
|
static circleToLine(circleCenter: Vector2, radius: number, lineFrom: Vector2, lineTo: Vector2): boolean;
|
||||||
|
|||||||
@@ -4214,12 +4214,14 @@ var TimeUtils = /** @class */ (function () {
|
|||||||
}());
|
}());
|
||||||
var es;
|
var es;
|
||||||
(function (es) {
|
(function (es) {
|
||||||
/** 贝塞尔帮助类 */
|
/**
|
||||||
|
* 三次方和二次方贝塞尔帮助器(cubic and quadratic bezier helper)
|
||||||
|
*/
|
||||||
var Bezier = /** @class */ (function () {
|
var Bezier = /** @class */ (function () {
|
||||||
function Bezier() {
|
function Bezier() {
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 二次贝塞尔曲线
|
* 求解二次曲折线
|
||||||
* @param p0
|
* @param p0
|
||||||
* @param p1
|
* @param p1
|
||||||
* @param p2
|
* @param p2
|
||||||
@@ -5886,7 +5888,7 @@ var es;
|
|||||||
var Collisions = /** @class */ (function () {
|
var Collisions = /** @class */ (function () {
|
||||||
function Collisions() {
|
function Collisions() {
|
||||||
}
|
}
|
||||||
Collisions.isLineToLine = function (a1, a2, b1, b2) {
|
Collisions.lineToLine = function (a1, a2, b1, b2) {
|
||||||
var b = es.Vector2.subtract(a2, a1);
|
var b = es.Vector2.subtract(a2, a1);
|
||||||
var d = es.Vector2.subtract(b2, b1);
|
var d = es.Vector2.subtract(b2, b1);
|
||||||
var bDotDPerp = b.x * d.y - b.y * d.x;
|
var bDotDPerp = b.x * d.y - b.y * d.x;
|
||||||
@@ -5902,23 +5904,27 @@ var es;
|
|||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
Collisions.lineToLineIntersection = function (a1, a2, b1, b2) {
|
Collisions.lineToLineIntersection = function (a1, a2, b1, b2, intersection) {
|
||||||
var intersection = es.Vector2.zero;
|
if (intersection === void 0) { intersection = new es.Vector2(); }
|
||||||
|
intersection.x = 0;
|
||||||
|
intersection.y = 0;
|
||||||
var b = es.Vector2.subtract(a2, a1);
|
var b = es.Vector2.subtract(a2, a1);
|
||||||
var d = es.Vector2.subtract(b2, b1);
|
var d = es.Vector2.subtract(b2, b1);
|
||||||
var bDotDPerp = b.x * d.y - b.y * d.x;
|
var bDotDPerp = b.x * d.y - b.y * d.x;
|
||||||
// 如果b*d = 0,表示这两条直线平行,因此有无穷个交点
|
// 如果b*d = 0,表示这两条直线平行,因此有无穷个交点
|
||||||
if (bDotDPerp == 0)
|
if (bDotDPerp == 0)
|
||||||
return intersection;
|
return false;
|
||||||
var c = es.Vector2.subtract(b1, a1);
|
var c = es.Vector2.subtract(b1, a1);
|
||||||
var t = (c.x * d.y - c.y * d.x) / bDotDPerp;
|
var t = (c.x * d.y - c.y * d.x) / bDotDPerp;
|
||||||
if (t < 0 || t > 1)
|
if (t < 0 || t > 1)
|
||||||
return intersection;
|
return false;
|
||||||
var u = (c.x * b.y - c.y * b.x) / bDotDPerp;
|
var u = (c.x * b.y - c.y * b.x) / bDotDPerp;
|
||||||
if (u < 0 || u > 1)
|
if (u < 0 || u > 1)
|
||||||
return intersection;
|
return false;
|
||||||
intersection = es.Vector2.add(a1, new es.Vector2(t * b.x, t * b.y));
|
var temp = es.Vector2.add(a1, new es.Vector2(t * b.x, t * b.y));
|
||||||
return intersection;
|
intersection.x = temp.x;
|
||||||
|
intersection.y = temp.y;
|
||||||
|
return true;
|
||||||
};
|
};
|
||||||
Collisions.closestPointOnLine = function (lineA, lineB, closestTo) {
|
Collisions.closestPointOnLine = function (lineA, lineB, closestTo) {
|
||||||
var v = es.Vector2.subtract(lineB, lineA);
|
var v = es.Vector2.subtract(lineB, lineA);
|
||||||
@@ -5937,8 +5943,10 @@ var es;
|
|||||||
return es.Vector2.distanceSquared(circleCenter, point) < radius * radius;
|
return es.Vector2.distanceSquared(circleCenter, point) < radius * radius;
|
||||||
};
|
};
|
||||||
Collisions.rectToCircle = function (rect, cPosition, cRadius) {
|
Collisions.rectToCircle = function (rect, cPosition, cRadius) {
|
||||||
|
// 检查矩形是否包含圆的中心点
|
||||||
if (this.rectToPoint(rect.x, rect.y, rect.width, rect.height, cPosition))
|
if (this.rectToPoint(rect.x, rect.y, rect.width, rect.height, cPosition))
|
||||||
return true;
|
return true;
|
||||||
|
// 对照相关边缘检查圆圈
|
||||||
var edgeFrom;
|
var edgeFrom;
|
||||||
var edgeTo;
|
var edgeTo;
|
||||||
var sector = this.getSector(rect.x, rect.y, rect.width, rect.height, cPosition);
|
var sector = this.getSector(rect.x, rect.y, rect.width, rect.height, cPosition);
|
||||||
@@ -5985,25 +5993,25 @@ var es;
|
|||||||
if ((both & PointSectors.top) != 0) {
|
if ((both & PointSectors.top) != 0) {
|
||||||
edgeFrom = new es.Vector2(rect.x, rect.y);
|
edgeFrom = new es.Vector2(rect.x, rect.y);
|
||||||
edgeTo = new es.Vector2(rect.x + rect.width, rect.y);
|
edgeTo = new es.Vector2(rect.x + rect.width, rect.y);
|
||||||
if (this.isLineToLine(edgeFrom, edgeTo, lineFrom, lineTo))
|
if (this.lineToLine(edgeFrom, edgeTo, lineFrom, lineTo))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if ((both & PointSectors.bottom) != 0) {
|
if ((both & PointSectors.bottom) != 0) {
|
||||||
edgeFrom = new es.Vector2(rect.x, rect.y + rect.height);
|
edgeFrom = new es.Vector2(rect.x, rect.y + rect.height);
|
||||||
edgeTo = new es.Vector2(rect.x + rect.width, rect.y + rect.height);
|
edgeTo = new es.Vector2(rect.x + rect.width, rect.y + rect.height);
|
||||||
if (this.isLineToLine(edgeFrom, edgeTo, lineFrom, lineTo))
|
if (this.lineToLine(edgeFrom, edgeTo, lineFrom, lineTo))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if ((both & PointSectors.left) != 0) {
|
if ((both & PointSectors.left) != 0) {
|
||||||
edgeFrom = new es.Vector2(rect.x, rect.y);
|
edgeFrom = new es.Vector2(rect.x, rect.y);
|
||||||
edgeTo = new es.Vector2(rect.x, rect.y + rect.height);
|
edgeTo = new es.Vector2(rect.x, rect.y + rect.height);
|
||||||
if (this.isLineToLine(edgeFrom, edgeTo, lineFrom, lineTo))
|
if (this.lineToLine(edgeFrom, edgeTo, lineFrom, lineTo))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if ((both & PointSectors.right) != 0) {
|
if ((both & PointSectors.right) != 0) {
|
||||||
edgeFrom = new es.Vector2(rect.x + rect.width, rect.y);
|
edgeFrom = new es.Vector2(rect.x + rect.width, rect.y);
|
||||||
edgeTo = new es.Vector2(rect.x + rect.width, rect.y + rect.height);
|
edgeTo = new es.Vector2(rect.x + rect.width, rect.y + rect.height);
|
||||||
if (this.isLineToLine(edgeFrom, edgeTo, lineFrom, lineTo))
|
if (this.lineToLine(edgeFrom, edgeTo, lineFrom, lineTo))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7061,14 +7069,14 @@ var es;
|
|||||||
}
|
}
|
||||||
RealtimeCollisions.intersectMovingCircleBox = function (s, b, movement, time) {
|
RealtimeCollisions.intersectMovingCircleBox = function (s, b, movement, time) {
|
||||||
// 计算将b按球面半径r扩大后的AABB
|
// 计算将b按球面半径r扩大后的AABB
|
||||||
var e = b.bounds;
|
var e = b.bounds.clone();
|
||||||
e.inflate(s.radius, s.radius);
|
e.inflate(s.radius, s.radius);
|
||||||
// 将射线与展开的矩形e相交,如果射线错过了e,则以无交点退出,否则得到交点p和时间t作为结果。
|
// 将射线与展开的矩形e相交,如果射线错过了e,则以无交点退出,否则得到交点p和时间t作为结果。
|
||||||
var ray = new es.Ray2D(es.Vector2.subtract(s.position, movement), s.position);
|
var ray = new es.Ray2D(es.Vector2.subtract(s.position, movement), s.position);
|
||||||
if (!e.rayIntersects(ray, time) && time.value > 1)
|
if (!e.rayIntersects(ray, time) && time.value > 1)
|
||||||
return false;
|
return false;
|
||||||
// 求交点
|
// 求交点
|
||||||
var point = es.Vector2.add(ray.start, es.Vector2.add(ray.direction, new es.Vector2(time.value)));
|
var point = es.Vector2.add(ray.start, es.Vector2.multiply(ray.direction, new es.Vector2(time.value)));
|
||||||
// 计算交点p位于b的哪个最小面和最大面之外。注意,u和v不能有相同的位集,它们之间必须至少有一个位集。
|
// 计算交点p位于b的哪个最小面和最大面之外。注意,u和v不能有相同的位集,它们之间必须至少有一个位集。
|
||||||
var u, v = 0;
|
var u, v = 0;
|
||||||
if (point.x < b.bounds.left)
|
if (point.x < b.bounds.left)
|
||||||
|
|||||||
2
source/bin/framework.min.js
vendored
2
source/bin/framework.min.js
vendored
File diff suppressed because one or more lines are too long
@@ -1,8 +1,10 @@
|
|||||||
module es {
|
module es {
|
||||||
/** 贝塞尔帮助类 */
|
/**
|
||||||
|
* 三次方和二次方贝塞尔帮助器(cubic and quadratic bezier helper)
|
||||||
|
*/
|
||||||
export class Bezier {
|
export class Bezier {
|
||||||
/**
|
/**
|
||||||
* 二次贝塞尔曲线
|
* 求解二次曲折线
|
||||||
* @param p0
|
* @param p0
|
||||||
* @param p1
|
* @param p1
|
||||||
* @param p2
|
* @param p2
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ module es {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class Collisions {
|
export class Collisions {
|
||||||
public static isLineToLine(a1: Vector2, a2: Vector2, b1: Vector2, b2: Vector2): boolean {
|
public static lineToLine(a1: Vector2, a2: Vector2, b1: Vector2, b2: Vector2): boolean {
|
||||||
let b = Vector2.subtract(a2, a1);
|
let b = Vector2.subtract(a2, a1);
|
||||||
let d = Vector2.subtract(b2, b1);
|
let d = Vector2.subtract(b2, b1);
|
||||||
let bDotDPerp = b.x * d.y - b.y * d.x;
|
let bDotDPerp = b.x * d.y - b.y * d.x;
|
||||||
@@ -33,8 +33,9 @@ module es {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static lineToLineIntersection(a1: Vector2, a2: Vector2, b1: Vector2, b2: Vector2): Vector2 {
|
public static lineToLineIntersection(a1: Vector2, a2: Vector2, b1: Vector2, b2: Vector2, intersection: Vector2 = new Vector2()): boolean {
|
||||||
let intersection = Vector2.zero;
|
intersection.x = 0;
|
||||||
|
intersection.y = 0;
|
||||||
|
|
||||||
let b = Vector2.subtract(a2, a1);
|
let b = Vector2.subtract(a2, a1);
|
||||||
let d = Vector2.subtract(b2, b1);
|
let d = Vector2.subtract(b2, b1);
|
||||||
@@ -42,20 +43,22 @@ module es {
|
|||||||
|
|
||||||
// 如果b*d = 0,表示这两条直线平行,因此有无穷个交点
|
// 如果b*d = 0,表示这两条直线平行,因此有无穷个交点
|
||||||
if (bDotDPerp == 0)
|
if (bDotDPerp == 0)
|
||||||
return intersection;
|
return false;
|
||||||
|
|
||||||
let c = Vector2.subtract(b1, a1);
|
let c = Vector2.subtract(b1, a1);
|
||||||
let t = (c.x * d.y - c.y * d.x) / bDotDPerp;
|
let t = (c.x * d.y - c.y * d.x) / bDotDPerp;
|
||||||
if (t < 0 || t > 1)
|
if (t < 0 || t > 1)
|
||||||
return intersection;
|
return false;
|
||||||
|
|
||||||
let u = (c.x * b.y - c.y * b.x) / bDotDPerp;
|
let u = (c.x * b.y - c.y * b.x) / bDotDPerp;
|
||||||
if (u < 0 || u > 1)
|
if (u < 0 || u > 1)
|
||||||
return intersection;
|
return false;
|
||||||
|
|
||||||
intersection = Vector2.add(a1, new Vector2(t * b.x, t * b.y));
|
let temp = Vector2.add(a1, new Vector2(t * b.x, t * b.y));
|
||||||
|
intersection.x = temp.x;
|
||||||
|
intersection.y = temp.y;
|
||||||
|
|
||||||
return intersection;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static closestPointOnLine(lineA: Vector2, lineB: Vector2, closestTo: Vector2) {
|
public static closestPointOnLine(lineA: Vector2, lineB: Vector2, closestTo: Vector2) {
|
||||||
@@ -80,9 +83,11 @@ module es {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static rectToCircle(rect: Rectangle, cPosition: Vector2, cRadius: number): boolean {
|
public static rectToCircle(rect: Rectangle, cPosition: Vector2, cRadius: number): boolean {
|
||||||
|
// 检查矩形是否包含圆的中心点
|
||||||
if (this.rectToPoint(rect.x, rect.y, rect.width, rect.height, cPosition))
|
if (this.rectToPoint(rect.x, rect.y, rect.width, rect.height, cPosition))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
// 对照相关边缘检查圆圈
|
||||||
let edgeFrom: Vector2;
|
let edgeFrom: Vector2;
|
||||||
let edgeTo: Vector2;
|
let edgeTo: Vector2;
|
||||||
let sector = this.getSector(rect.x, rect.y, rect.width, rect.height, cPosition);
|
let sector = this.getSector(rect.x, rect.y, rect.width, rect.height, cPosition);
|
||||||
@@ -135,28 +140,28 @@ module es {
|
|||||||
if ((both & PointSectors.top) != 0) {
|
if ((both & PointSectors.top) != 0) {
|
||||||
edgeFrom = new Vector2(rect.x, rect.y);
|
edgeFrom = new Vector2(rect.x, rect.y);
|
||||||
edgeTo = new Vector2(rect.x + rect.width, rect.y);
|
edgeTo = new Vector2(rect.x + rect.width, rect.y);
|
||||||
if (this.isLineToLine(edgeFrom, edgeTo, lineFrom, lineTo))
|
if (this.lineToLine(edgeFrom, edgeTo, lineFrom, lineTo))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((both & PointSectors.bottom) != 0) {
|
if ((both & PointSectors.bottom) != 0) {
|
||||||
edgeFrom = new Vector2(rect.x, rect.y + rect.height);
|
edgeFrom = new Vector2(rect.x, rect.y + rect.height);
|
||||||
edgeTo = new Vector2(rect.x + rect.width, rect.y + rect.height);
|
edgeTo = new Vector2(rect.x + rect.width, rect.y + rect.height);
|
||||||
if (this.isLineToLine(edgeFrom, edgeTo, lineFrom, lineTo))
|
if (this.lineToLine(edgeFrom, edgeTo, lineFrom, lineTo))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((both & PointSectors.left) != 0) {
|
if ((both & PointSectors.left) != 0) {
|
||||||
edgeFrom = new Vector2(rect.x, rect.y);
|
edgeFrom = new Vector2(rect.x, rect.y);
|
||||||
edgeTo = new Vector2(rect.x, rect.y + rect.height);
|
edgeTo = new Vector2(rect.x, rect.y + rect.height);
|
||||||
if (this.isLineToLine(edgeFrom, edgeTo, lineFrom, lineTo))
|
if (this.lineToLine(edgeFrom, edgeTo, lineFrom, lineTo))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((both & PointSectors.right) != 0) {
|
if ((both & PointSectors.right) != 0) {
|
||||||
edgeFrom = new Vector2(rect.x + rect.width, rect.y);
|
edgeFrom = new Vector2(rect.x + rect.width, rect.y);
|
||||||
edgeTo = new Vector2(rect.x + rect.width, rect.y + rect.height);
|
edgeTo = new Vector2(rect.x + rect.width, rect.y + rect.height);
|
||||||
if (this.isLineToLine(edgeFrom, edgeTo, lineFrom, lineTo))
|
if (this.lineToLine(edgeFrom, edgeTo, lineFrom, lineTo))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ module es {
|
|||||||
export class RealtimeCollisions {
|
export class RealtimeCollisions {
|
||||||
public static intersectMovingCircleBox(s: Circle, b: Box, movement: Vector2, time: Ref<number>): boolean {
|
public static intersectMovingCircleBox(s: Circle, b: Box, movement: Vector2, time: Ref<number>): boolean {
|
||||||
// 计算将b按球面半径r扩大后的AABB
|
// 计算将b按球面半径r扩大后的AABB
|
||||||
let e = b.bounds;
|
let e = b.bounds.clone();
|
||||||
e.inflate(s.radius, s.radius);
|
e.inflate(s.radius, s.radius);
|
||||||
|
|
||||||
// 将射线与展开的矩形e相交,如果射线错过了e,则以无交点退出,否则得到交点p和时间t作为结果。
|
// 将射线与展开的矩形e相交,如果射线错过了e,则以无交点退出,否则得到交点p和时间t作为结果。
|
||||||
@@ -11,7 +11,7 @@ module es {
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
// 求交点
|
// 求交点
|
||||||
let point = Vector2.add(ray.start, Vector2.add(ray.direction, new Vector2(time.value)));
|
let point = Vector2.add(ray.start, Vector2.multiply(ray.direction, new Vector2(time.value)));
|
||||||
|
|
||||||
// 计算交点p位于b的哪个最小面和最大面之外。注意,u和v不能有相同的位集,它们之间必须至少有一个位集。
|
// 计算交点p位于b的哪个最小面和最大面之外。注意,u和v不能有相同的位集,它们之间必须至少有一个位集。
|
||||||
let u, v = 0;
|
let u, v = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user