Определить аффинное преобразование, которое превращает одну плоскость в параллельную плоскость к другой

Как я могу определить аффинное преобразование CGAL (Aff_transformation_3), которое преобразует одну плоскость (plane1) в параллельную плоскость к другой (plane2)?

Предположим, что у меня есть две плоскости объекта:

Plane_3  pl1;
Plane_3  pl2;

и они не параллели, как определить этот вид аффинной трансформации?

Aff_transformation_3 t3 = ??? (pl1, pl2);

Я консультировался с этим вопросом и вашим ответом: CGAL: Матрица преобразования для вращения с учетом двух линий / векторов / направлений, но я не знаю, как это может помочь. У меня есть две плоскости, но в трехмерных измерениях.

Благодарю.

0

Решение

Я не знаю, как двумерное аффинное преобразование (Aff_transformation_2) может помочь мне применить трехмерное аффинное преобразование (Aff_transformation_3).

Тем не менее, я нашел решение своего вопроса. Это может быть немного кода, который я надеюсь помочь кому-то.

typedef CGAL::Cartesian<double>         KC;

typedef KC::Line_3                      Line3;
typedef KC::Vector_3                    Vector3;
typedef KC::Plane_3                     Plane3;
typedef CGAL::Aff_transformation_3<KC>  Transform3;

// forwards
struct axis_angle;

typedef boost::shared_ptr<axis_angle>   RAxisAngle;

struct axis_angle
{
axis_angle()
{
angle = 0;
axis = Vector3(0.0, 0.0, 0.0);
}

double  angle;
Vector3 axis;
};

Vector3 normalize(const Vector3 &v)
{
ldouble len = ::sqrt(v.squared_length());

if (len == 0.0)
return v;

return v / len;
}

// return the angle and axis from two planes that there are not parallels
RAxisAngle axis_angle_from_planes(const Plane3 &pln1, const Plane3 &pln2)
{
RAxisAngle result = RAxisAngle(new axis_angle());

Vector3 norm1 = pln1.orthogonal_vector();
Vector3 norm2 = pln2.orthogonal_vector();

double dot_r = norm1 * norm2;
double len_r = ::sqrt(norm1.squared_length() * norm2.squared_length());

if (len_r)
result->angle = ::acos(dot_r / len_r);
else
result->angle = 0.0;

Line3 l1;
CGAL::Object obj_cgal = CGAL::intersection(pln1, pln2);
if (CGAL::assign(l1, obj_cgal))
{
result->axis = normalize(l1.to_vector());
}
else
{
// when planes are parallels, then use some basic axis
result->axis = Vector3(1.0, 0.0, 0.0);
}

return result;
}

// return a CGAL affine transformation that is builded from a 3x3 matrix
// this transformation is for rotate an object from axis and angle
// http://en.wikipedia.org/wiki/Transformation_matrix
// http://en.wikipedia.org/wiki/Rotation_matrix
// http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToMatrix/index.htm
Transform3 axis_angle_to_matrix(const RAxisAngle &aa)
{
double tmp1, tmp2;

double c = ::cos(aa->angle);
double s = ::sin(aa->angle);
double t = 1.0 - c;

double m00 = c + aa->axis.x() * aa->axis.x() * t;
double m11 = c + aa->axis.y() * aa->axis.y() * t;
double m22 = c + aa->axis.z() * aa->axis.z() * t;

tmp1 = aa->axis.x() * aa->axis.y() * t;
tmp2 = aa->axis.z() * s;
double m10 = tmp1 + tmp2;
double m01 = tmp1 - tmp2;

tmp1 = aa->axis.x() * aa->axis.z() * t;
tmp2 = aa->axis.y() * s;
double m20 = tmp1 - tmp2;
double m02 = tmp1 + tmp2;

tmp1 = aa->axis.y() * aa->axis.z() * t;
tmp2 = aa->axis.x() * s;
double m21 = tmp1 + tmp2;
double m12 = tmp1 - tmp2;

return Transform3(m00, m01, m02, m10, m11, m12, m20, m21, m22);
}

Тогда я могу использовать там как это:

RAxisAngle aa = axis_angle_from_planes(plane1, plane2);
Transform3 t3 = axis_angle_to_matrix(aa);

Plane2 new_transform_plane = plane1.transform(t3);

или, может быть, точка этой плоскости:

Point3 new_transform_point = point_of_plane1.transform(t3);

Спасибо за предоставленную мне возможность опубликовать мое маленькое решение.

1

Другие решения