4.線分と線分のあたり判定
線分と線分の当たり判定をやります
線と線の当たり判定と違う点は範囲が決まっている点です。
ベクトルが違うだけでは、重なる訳ではないので、そのあたりの判定が必要になります。
まずは、線分の定義からです。
/**
* line segment
*
* point1:Vector2D
* point2:Vector2D
*/
var LineSegment2D = class LineSegment2D {
constructor(point1,point2){
this.point1 = point1;
this.point2 = point2;
}
}
2点間の距離をもつ、線分クラスLineSegment2Dを用意しました。
続いて当たり判定を行なっている関数です
線分と線分との当たり判定
/**
* segment1:Segment
* segment2:Segment
*
* return boolean
*/
function isSegmentsCollide(segment1,segment2){
// 線分の方向をチェックするためのベクトル
var axisA = new Line();
var axisB = new Line();
// 線分1のベクトルに対して、線分2が片側にあるかチェック
axisA.base = segment1.point1;
axisA.direction = subtractVector(segment1.point2,segment1.point1);
if(onOneSide(axisA,segment2)){
return false;
}
// 同じく
axisB.base = segment2.point1;
axisB.direction = subtractVector(segment2.point2,segment2.point1);
if(onOneSide(axisB,segment1)){
return false;
}
// 同じベクトルをもつケース
if(isParallelVector(axisA.direction,axisB.direction)){
var rangeA = getProjectSegment(segment1,axisA.direction);
var rangeB = getProjectSegment(segment2,axisA.direction);
// 重なっているか
return isOverLappingRanges(rangeA,rangeB);
}
else{
return true;
}
}
線分が片側にあるか判定する
線分が重なっているかを判定するにあたりチェックする点は、
一つの線分ともう一つの線分のベクトルが交差せず、片側のみにあるかということと、
同じベクトルの線分だった場合に、範囲が重なっていることで判定します。
ここで、片側にあるということを判定している、
onOneSide関数を見ていきます
/*
* 一つの軸を基準にその軸の片側をこえないかどうか
*
* axis:Line
* segment:Segment
*/
function onOneSide(axis,segment){
var d1 = new Vector2D();
d1 = subtractVector(segment.point1,axis.base);
var d2 = new Vector2D();
d2 = subtractVector(segment.point2,axis.base);
var n = new Vector2D();
n = rotateVector90(axis.direction);
// 同じ方向だということを返す
return dotProduct2D(n,d1) * dotProduct2D(n,d2) > 0;
}
関数だけ見るとわかりにくいですが、
この関数を図で表示すると非常にわかりやすいです。
判定すべき、二つの線分のうちの一つを基準のベクトルとして定義し
もう一方を線分として扱います
ベクトル内の点をbaseとし、線分の始点と終点をベクトルで結び、それぞれd1、d2とします。
ベクトルaxisの垂直ベクトルnとd1、d2の内積を調べます。
内積の性質により、axisを軸として、同じ方向にいるかを判定できます
今度は、逆にして上記と同じ判定をします
すると、線分が線分の範囲内で交差していることがわかります。
これは、図にして表すとわかりやすいです
上記以外の場合は、同じベクトルを持つケースということになります。
ですので、線分が同じ範囲内にあるかをチェックしておしまいです
線と線の当たり判定サンプル
サンプルをcanvasを使って表示してあります。
ソースとともに確認してください