Ich versuche, einen Schnittpunkttest mit Ray Casting durchzuführen (nicht sicher, ob der Begriff korrekt ist, bitte verzeihen Sie mir, wenn nicht) und gebe die Schnittpunkte als Punktwolke aus. Die Punktwolke zeigt die Krümmung (nur auf der Z-Achse, die Die Punktwolke ist auf der Y-Achse vollständig flach, und die horizontale Achse in diesem Bild ist die X-Achse.
Ich habe Konzepte von der Scratchapixel-Website ausgeliehen, insbesondere http://scratchapixel.com/lessons/3d-basic-rendering/minimal-ray-tracer-rendering-simple-shapes/ray-box-intersection .
Im Wesentlichen generiere ich 16 Strahlen, alle mit demselben Ursprungsvektor. Die Richtungsvektoren beginnen bei +15 Grad in der YZ-Ebene und setzen sich in Schritten von -2 Grad bis -15 fort. Ich habe einen achsenausgerichteten Begrenzungsrahmen, mit dem ich den Schnittpunkt teste. Ich benutze eine Rotationstransformation, um die 16 Strahlen gegen den Uhrzeigersinn um die Z-Achse zu drehen. Ich führe den Schnittpunkttest für alle 16 Strahlen mit jeweils 0,1 Grad durch. Wenn er wahr ist, füge ich den Punkt zur Punktwolke hinzu.
Hier ist mein Kreuzungscode:
bool test_intersect(Box b, Ray r, Vec3f& intersect_point)
{
float txmin = 0.0f, txmax = 0.0f, tymin = 0.0f, tymax = 0.0f, tzmin = 0.0f, tzmax = 0.0f;
float t_min = 0.0f, t_max = 0.0f, t = 0.0f;
// Determine inverse direction of ray to alleviate 0 = -0 issues
Vec3f inverse_direction(1 / r.direction.x, 1 / r.direction.y, 1 / r.direction.z);
// Solving box_min/box_max0 = O + Dt
txmin = (b.box_min.x - r.origin.x) * inverse_direction.x;
txmax = (b.box_max.x - r.origin.x) * inverse_direction.x;
tymin = (b.box_min.y - r.origin.y) * inverse_direction.y;
tymax = (b.box_max.y - r.origin.y) * inverse_direction.y;
tzmin = (b.box_min.z - r.origin.z) * inverse_direction.z;
tzmax = (b.box_max.z - r.origin.z) * inverse_direction.z;
// Depending on direction of ray tmin may > tmax, so we may need to swap
if (txmin > txmax) std::swap(txmin, txmax);
if (tymin > tymax) std::swap(tymin, tymax);
if (tzmin > tzmax) std::swap(tzmin, tzmax);
t_min = txmin;
t_max = txmax;
// If t-value of a min is greater than t-value of max,
// we missed the object in that plane.
if ((t_min > tymax) || (tymin > t_max))
return false;
if (tymin > t_min)
t_min = tymin;
if (tymax < t_max)
t_max = tymax;
if ((t_min > tzmax) || (tzmin > t_max))
return false;
if (tzmin > t_min)
t_min = tzmin;
if (tzmax < t_max)
t_max = tzmax;
if (t_min > 0)
t = t_min;
else
if (t_max > 0)
t = t_max;
else
return false;
intersect_point.x = r.origin.x + r.direction.x * t;
intersect_point.y = r.origin.y + r.direction.y * t;
intersect_point.z = r.origin.z + r.direction.z * t;
return true;
}
Und meine Rotation:
// Rotation around z axis, for rotating array and checking beam intersections
void transform_rotate_z(Vec3f& in_vector, float angle)
{
float radians = angle * (M_PI / 180);
float result_x = cos(radians) * in_vector.x + -sin(radians) * in_vector.y;
float result_y = sin(radians) * in_vector.x + cos(radians) * in_vector.y;
in_vector.x = result_x;
in_vector.y = result_y;
}
Ich habe mir eine ganze Weile den Kopf zerbrochen, aber ich kann anscheinend nicht feststellen, wie ich diese Krümmung verhindern kann. Ich bin sicher, ich übersehen etwas Einfaches. Ich wäre Ihnen für jede Hilfe dankbar, die Sie leisten können.
EDIT 18.09.16: Es stellte sich heraus, dass ich fälschlicherweise geglaubt hatte, dass physikalische LIDAR-Einheiten eine algorithmische Methode zum "Begradigen" der Kurven haben, was nicht der Fall ist! Die Ausgabe soll wie im Bild oben aussehen.