calculate angle when set volume

This commit is contained in:
Filip Sykala - NTB T15p 2023-02-20 14:50:17 +01:00
parent d6b8163975
commit ead192b43b
3 changed files with 61 additions and 50 deletions

View file

@ -1544,7 +1544,7 @@ std::optional<Vec2d> Emboss::ProjectZ::unproject(const Vec3d &p, double *depth)
Vec3d Emboss::suggest_up(const Vec3d normal, double up_limit)
{
// Normal must be 1
assert(is_approx(normal.norm(), 1.));
assert(is_approx(normal.squaredNorm(), 1.));
// wanted up direction of result
Vec3d wanted_up_side =
@ -1560,28 +1560,45 @@ Vec3d Emboss::suggest_up(const Vec3d normal, double up_limit)
return wanted_up_dir;
}
std::optional<float> Emboss::calc_up(const Transform3d &tr, double up_limit)
{
auto tr_linear = tr.linear();
// z base of transformation ( tr * UnitZ )
Vec3d normal = tr_linear.col(2);
// scaled matrix has base with different size
normal.normalize();
Vec3d suggested = suggest_up(normal);
assert(is_approx(suggested.squaredNorm(), 1.));
Vec3d up = tr_linear.col(1); // tr * UnitY()
up.normalize();
double dot = suggested.dot(up);
if (dot >= 1. || dot <= -1.)
return {}; // zero angle
Matrix3d m;
m.row(0) = up;
m.row(1) = suggested;
m.row(2) = normal;
double det = m.determinant();
return atan2(det, dot);
}
Transform3d Emboss::create_transformation_onto_surface(const Vec3d &position,
const Vec3d &normal,
float up_limit)
{
// up and emboss direction for generated model
Vec3d text_up_dir = Vec3d::UnitY();
Vec3d text_emboss_dir = Vec3d::UnitZ();
// is normalized ?
assert(is_approx(normal.squaredNorm(), 1.));
// wanted up direction of result
Vec3d wanted_up_side = Vec3d::UnitZ();
if (std::fabs(normal.z()) > up_limit) wanted_up_side = Vec3d::UnitY();
// up and emboss direction for generated model
Vec3d up_dir = Vec3d::UnitY();
Vec3d emboss_dir = Vec3d::UnitZ();
// after cast from float it needs to be normalized again
assert(is_approx(normal.norm(), 1.));
// create perpendicular unit vector to surface triangle normal vector
// lay on surface of triangle and define up vector for text
Vec3d wanted_up_dir = normal
.cross(wanted_up_side)
.cross(normal);
// normal3d is NOT perpendicular to normal_up_dir
wanted_up_dir.normalize();
Vec3d wanted_up_dir = suggest_up(normal, up_limit);
// perpendicular to emboss vector of text and normal
Vec3d axis_view;
@ -1591,25 +1608,24 @@ Transform3d Emboss::create_transformation_onto_surface(const Vec3d &position,
axis_view = Vec3d::UnitY();
angle_view = M_PI;
} else {
axis_view = text_emboss_dir.cross(normal);
angle_view = std::acos(text_emboss_dir.dot(normal)); // in rad
axis_view = emboss_dir.cross(normal);
angle_view = std::acos(emboss_dir.dot(normal)); // in rad
axis_view.normalize();
}
Eigen::AngleAxis view_rot(angle_view, axis_view);
Vec3d wanterd_up_rotated = view_rot.matrix().inverse() * wanted_up_dir;
wanterd_up_rotated.normalize();
double angle_up = std::acos(text_up_dir.dot(wanterd_up_rotated));
double angle_up = std::acos(up_dir.dot(wanterd_up_rotated));
// text_view and text_view2 should have same direction
Vec3d text_view2 = text_up_dir.cross(wanterd_up_rotated);
Vec3d diff_view = text_emboss_dir - text_view2;
Vec3d text_view = up_dir.cross(wanterd_up_rotated);
Vec3d diff_view = emboss_dir - text_view;
if (std::fabs(diff_view.x()) > 1. ||
std::fabs(diff_view.y()) > 1. ||
std::fabs(diff_view.z()) > 1.) // oposit direction
angle_up *= -1.;
Eigen::AngleAxis up_rot(angle_up, text_emboss_dir);
Eigen::AngleAxis up_rot(angle_up, emboss_dir);
Transform3d transform = Transform3d::Identity();
transform.translate(position);