Пример #1
0
        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);
        }
Пример #2
0
        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);
        }