public static float GetDistanceWithParallelogram(Vector3 anchorPoint, Vector3 baseVertex, Vector3 edge1, Vector3 edge2, out Vector3 location) { // 平行四辺形のある平面の法線 Vector3 normOnParallelogram = Vector3.Normalize(Vector3.Cross(edge1, edge2)); // baseVertexへ Vector3 toBaseVertex = baseVertex - anchorPoint; // anchorPointから平行四辺形のある平面への最短ベクトル(垂線) Vector3 perpendicular = normOnParallelogram * Vector3.Dot(toBaseVertex, normOnParallelogram); // 垂線の足 Vector3 foot = anchorPoint + perpendicular; // 垂線の足が平行四辺形の中かどうか if (GeometryCalc.PointOverParallelogram(foot, baseVertex, edge1, edge2)) { location = foot; return(perpendicular.Length()); } Vector3 oppositeVertex = baseVertex + edge1 + edge2; Vector3 location1, location2, location3, location4; float distance1 = GeometryCalc.GetDistanceWithLine(anchorPoint, baseVertex, baseVertex + edge1, out location1); float distance2 = GeometryCalc.GetDistanceWithLine(anchorPoint, baseVertex, baseVertex + edge2, out location2); float distance3 = GeometryCalc.GetDistanceWithLine(anchorPoint, oppositeVertex, oppositeVertex - edge1, out location3); float distance4 = GeometryCalc.GetDistanceWithLine(anchorPoint, oppositeVertex, oppositeVertex - edge2, out location4); float minDistance = new float[] { distance1, distance2, distance3, distance4 }.Min(); if (minDistance == distance1) { location = location1; } else if (minDistance == distance2) { location = location2; } else if (minDistance == distance3) { location = location3; } else { location = location4; } return(minDistance); }
public static bool GetCollisionParallelogram(Vector3 lineSource, Vector3 lineDestination, Vector3 baseVertex, Vector3 edge1, Vector3 edge2, out float distance) { distance = float.MaxValue; Vector3 lineEdge = lineDestination - lineSource; // 平行四辺形のある平面の法線 Vector3 normOnParallelogram = Vector3.Normalize(Vector3.Cross(edge1, edge2)); // baseVertexへ Vector3 toBaseVertex = baseVertex - lineSource; // 平面の法線成分 float toBaseVertexDistance = Vector3.Dot(normOnParallelogram, toBaseVertex); float lineEdgeDistance = Vector3.Dot(normOnParallelogram, lineEdge); if (lineEdgeDistance == 0) { // 引数の線分と平行四辺形が平行な時 return(false); } float ratio = toBaseVertexDistance / lineEdgeDistance; if (ratio < 0 && 1 < ratio) { // 向きが逆であるか,長さが足りない return(false); } // 引数の線分と平行四辺形のある平面との交点へのベクトル Vector3 lineEdgeToParallelogram = lineEdge * ratio; // 引数の線分と平行四辺形のある平面との交点 Vector3 onPlane = lineSource + lineEdgeToParallelogram; if (GeometryCalc.PointOverParallelogram(onPlane, baseVertex, edge1, edge2)) { distance = lineEdgeToParallelogram.Length(); return(true); } return(false); }