Je recherche un algorithme qui détermine les points d'intersection proches et loin entre un segment de ligne et une boîte alignée sur l'axe.
Voici ma définition de méthode: p>
public static Point3D[] IntersectionOfLineSegmentWithAxisAlignedBox(
Point3D rayBegin, Point3D rayEnd, Point3D boxCenter, Size3D boxSize)
3 Réponses :
Eh bien, pour une boîte alignée à l'axe, il est assez simple: vous devez trouver l'intersection de votre rayon avec 6 plans (définis par les faces de la boîte), puis vérifiez les points que vous avez trouvés contre les limites de coordonnées de la boîte. P >
Voici ce que j'ai fini par utiliser:
public static double GetCoordinate(this Point3D point, Axis axis)
{
switch (axis)
{
case Axis.X:
return point.X;
case Axis.Y:
return point.Y;
case Axis.Z:
return point.Z;
default:
throw new ArgumentException();
}
}
public static double GetCoordinate(this Vector3D vector, Axis axis)
{
switch (axis)
{
case Axis.X:
return vector.X;
case Axis.Y:
return vector.Y;
case Axis.Z:
return vector.Z;
default:
throw new ArgumentException();
}
}
Au moins un peu d'explication ici . Cet algorithme calcule la fraction de la ligne que vous devez passer du point de départ jusqu'à ce que les intersections. Cela le fait en examinant chaque axe comme un problème unidimensionnel, où il trouve la proportion de la ligne, qui doit être ajoutée pour commencer, pour atteindre l'intersection.
Cela pourrait être amélioré en cochant d'abord la boîte de sélection: si (commence> max || fin
version optimisée de la réponse. Il n'y a aucune raison de faire des allocations ou des recherches.
public struct Ray3
{
public Vec3 origin, direction;
public bool IntersectRayBox(Box3 box, out Vec3 point1, out Vec3 point2)
{
var min = (box.center - (box.size / 2)) - origin;
var max = (box.center + (box.size / 2)) - origin;
float near = float.MinValue;
float far = float.MaxValue;
// X
float t1 = min.x / direction.x;
float t2 = max.x / direction.x;
float tMin = Math.Min(t1, t2);
float tMax = Math.Max(t1, t2);
if (tMin > near) near = tMin;
if (tMax < far) far = tMax;
if (near > far || far < 0)
{
point1 = Vec3.zero;
point2 = Vec3.zero;
return false;
}
// Y
t1 = min.y / direction.y;
t2 = max.y / direction.y;
tMin = Math.Min(t1, t2);
tMax = Math.Max(t1, t2);
if (tMin > near) near = tMin;
if (tMax < far) far = tMax;
if (near > far || far < 0)
{
point1 = Vec3.zero;
point2 = Vec3.zero;
return false;
}
// Z
t1 = min.z / direction.z;
t2 = max.z / direction.z;
tMin = Math.Min(t1, t2);
tMax = Math.Max(t1, t2);
if (tMin > near) near = tMin;
if (tMax < far) far = tMax;
if (near > far || far < 0)
{
point1 = Vec3.zero;
point2 = Vec3.zero;
return false;
}
point1 = origin + direction * near;
point2 = origin + direction * far;
return true;
}
}
Je ne connais pas l'algorithme mais je pense que revenir
null code> est un peu inhabituel. Un tableau vide est beaucoup plus agréable, il est clair qu'il n'y a pas de points qui se croisent (longueur = 0), et vous n'aurez pas besoin d'effectuer des chèques nuls dans le code consommateur.Juste être difficile, mais un rayon n'a pas de point final - c'est infini dans une direction. Une ligne qui a un point de départ et de fin est un segment de ligne.
Bon point, @Richk ... J'ai corrigé ma question.
Bon point, Moine crédulelle, j'ai corrigé ma question.
géométricools.com/libmathematics/intersection/.../a> est toujours un endroit idéal pour regarder Pour ce genre de chose :)