현재 (열린 발명가의 경우 3D 공간에서 포인트로 구성된 (곡선) 선이 있지만이 문제에 대한 해결책은 비 특정 제품).3D 선에서 투영 된 리본을 "앞으로 직면"하는 방법으로 시각화하는 방법
우리는 리본에서 직각으로 돌출 된 리본을 묘사하고 카메라가 회전 할 때 항상 카메라를 마주 보게하는 서페이스를 그려 보려고합니다.
(예를 들어, 사용자는 라인 자체가 측면의 하나 인 라인의 곡선을 설명하는 리본을 볼 수 있습니다. 그리고 나서 장면 주위를 회전 할 때 리본이 라인을 "회전"하므로 항상 항상 사용자)
에 직면하고 우리는이 :
카메라
라인을 따라 각 지점의 위치의 위치와 회전
우리는 접근 점의 각 쌍에 대해 카메라에 직각 인 평면과 그 점들 사이의 선에 직각 인 평면과 교차하는 선을 찾고 그에 따라 설정된 거리를 투영하는 방법을 생각했습니다 그러나 이것은 올바른 결과에 가까운 곳에서 우리에게 아무런 도움도되지 못했습니다. (아래의 오작동 코드).
이 접근법이 맞습니까? 그렇다면 아래 코드에서 설명해야하는 것은 무엇입니까?
그렇지 않다면 핵심 목표 (리본은 항상 사용자를 향하고 있음)를 어떻게 달성 할 수 있습니까?
SbVec3f getOuterPoint(SbVec3f p3, const float ribbon_width, float cosine, float sine)
{
return SbVec3f(p3[0] + ribbon_width*cosine, p3[1] - ribbon_width*sine, p3[2]);
}
SbVec3f getOuterPoint(SbVec3f old_p3, SbVec3f other_point, const float ribbon_width)
{
float oangle = atan2(old_p3[1] - other_point[1], old_p3[0] - other_point[0]);
float ocosine = cosf(oangle);
float osine = sinf(oangle);
return getOuterPoint(old_p3, ribbon_width, ocosine, osine);
}
SbVec3f getOuterPoint(SbVec3f p0, SbVec3f p1, const float ribbon_width, SoCamera* camera)
{
SbVec3f axis;
float angle;
SoSFRotation camera_rotation = camera->orientation;
camera_rotation.getValue(axis, angle);
//std::cout << axis[0] << " " << axis[1] << " " << axis[2] << ":" << angle << std::endl;
const SbVec3f &camera_position = camera->position.getValue();
SbVec3f camera_axis = axis;
SbVec3f well_axis = p1 - p0;
well_axis.normalize();
camera_axis.normalize();
float cam_constant[3] = { -p1[0], -p1[1], -p1[2] };
float well_constant[3] = { -p1[0], -p1[1], -p1[2] };
/*
//float p1_constant = camera_axis[0] * p1[0] + camera_axis[1] * p1[1] + camera_axis[2] * p1[2]
// - (camera_axis[0] * camera_position[0] + camera_axis[1] * camera_position[1] + camera_axis[2] * camera_position[2]);
//// X, Y, Z are unknown
//float line_unknown = camera_axis[0] * X + camera_axis[1] * Y + camera_axis[2] * Z;
//
//
// camera_axis.x * (x - p1[0]) + camera_axis.y * (y - p1[1]) + camera_axis.z * (z - p1[2]) = 0 (1)
// well_axis.x * (x - p1[0]) + well_axis.y * (y - p1[1]) + well_axis.z * (z - p1[2]) = 0 (2)
// let z become free variable t
// camera_axis.x * (x - p1[0]) + camera_axis.y * (y - p1[1]) = - camera_axis.z * (t - p1[2])
// well_axis.x * (x - p1[0]) + well_axis.y * (y - p1[1]) = - well_axis.z * (t - p1[2])
// camera_axis.x * (x - p1[0]) + camera_axis.y * (y - p1[1]) = - camera_axis.z * t - camera_axis.z * p1[2]
// well_axis.x * (x - p1[0]) + well_axis.y * (y - p1[1]) = - well_axis.z * t - well_axis.z * p1[2]
// camera_axis.x * x + camera_axis.y * y = - camera_axis.z * t - camera_axis.z * p1[2] + camera_axis.x *p1[0] + camera_axis.y * p1[1] (3)
// well_axis.x * x + well_axis.y * y = - well_axis.z * t - well_axis.z * p1[2] + well_axis.x *p1[0] + well_axis.y * p1[1] (4)
(3) * well_axis.x:
well_axis.x * camera_axis.x * x + well_axis.x * camera_axis.y * y = well_axis.x * (- camera_axis.z * t - camera_axis.z * p1[2] + camera_axis.x *p1[0] + camera_axis.y * p1[1])
(4) * camera_axis.x
camera_axis.x * well_axis.x * x + camera_axis.x * well_axis.y * y = camera_axis.x * (- well_axis.z * t - well_axis.z * p1[2] + well_axis.x *p1[0] + well_axis.y * p1[1])
Subtracting
well_axis.x * camera_axis.y * y - camera_axis.x * well_axis.y * y = well_axis.x * (- camera_axis.z * t - camera_axis.z * p1[2] + camera_axis.x *p1[0] + camera_axis.y * p1[1]) - camera_axis.x * (- well_axis.z * t - well_axis.z * p1[2] + well_axis.x *p1[0] + well_axis.y * p1[1])
(well_axis.x * camera_axis.y - camera_axis.x * well_axis.y) * y = well_axis.x * (- camera_axis.z * t - camera_axis.z * p1[2] + camera_axis.x *p1[0] + camera_axis.y * p1[1]) - camera_axis.x * (- well_axis.z * t - well_axis.z * p1[2] + well_axis.x *p1[0] + well_axis.y * p1[1])
y = well_axis.x * (- camera_axis.z * t - camera_axis.z * p1[2] + camera_axis.x *p1[0] + camera_axis.y * p1[1]) - camera_axis.x * (- well_axis.z * t - well_axis.z * p1[2] + well_axis.x *p1[0] + well_axis.y * p1[1])/(well_axis.x * camera_axis.y - camera_axis.x * well_axis.y)
(3) * well_axis.y
well_axis.y * camera_axis.x * x + well_axis.y * camera_axis.y * y = well_axis.y * (- camera_axis.z * t - camera_axis.z * p1[2] + camera_axis.x *p1[0] + camera_axis.y * p1[1])
(4) * camera_axis.y
camera_axis.y * well_axis.x * x + camera_axis.y * well_axis.y * y = camera_axis.y * (- well_axis.z * t - well_axis.z * p1[2] + well_axis.x *p1[0] + well_axis.y * p1[1])
Subtracting
x = well_axis.y * (- camera_axis.z * t - camera_axis.z * p1[2] + camera_axis.x *p1[0] + camera_axis.y * p1[1]) - camera_axis.y * (- well_axis.z * t - well_axis.z * p1[2] + well_axis.x *p1[0] + well_axis.y * p1[1])/well_axis.y * camera_axis.x - camera_axis.y * well_axis.x
So:
x = well_axis.y * (- camera_axis.z * t - camera_axis.z * p1[2] + camera_axis.x *p1[0] + camera_axis.y * p1[1]) - camera_axis.y * (- well_axis.z * t - well_axis.z * p1[2] + well_axis.x *p1[0] + well_axis.y * p1[1])/(well_axis.y * camera_axis.x - camera_axis.y * well_axis.x)
y = well_axis.x * (- camera_axis.z * t - camera_axis.z * p1[2] + camera_axis.x *p1[0] + camera_axis.y * p1[1]) - camera_axis.x * (- well_axis.z * t - well_axis.z * p1[2] + well_axis.x *p1[0] + well_axis.y * p1[1])/(well_axis.x * camera_axis.y - camera_axis.x * well_axis.y)
z = t
x = ((well_axis.z * camera_axis.y - camera_axis.z * well_axis.y) * t
- camera_axis.z * well_axis.y * p1[2]
+ camera_axis.x * well_axis.y * p1[0]
+ well_axis.z * camera_axis.y * p1[2]
- well_axis.x * camera_axis.y * p1[0])
/(well_axis.y * camera_axis.x - camera_axis.y * well_axis.x)
y = (- camera_axis.z * well_axis.x * t - camera_axis.z * well_axis.x * p1[2] + camera_axis.x * well_axis.x * p1[0] + camera_axis.y * well_axis.x * p1[1] + well_axis.z * camera_axis.x * t + well_axis.z * camera_axis.x * p1[2] - well_axis.x * camera_axis.x * p1[0] - well_axis.y * camera_axis.x * p1[1])/(well_axis.x * camera_axis.y - camera_axis.x * well_axis.y)
y = ((well_axis.z * camera_axis.x - camera_axis.z * well_axis.x) * t
- camera_axis.z * well_axis.x * p1[2]
+ camera_axis.y * well_axis.x * p1[1]
+ well_axis.z * camera_axis.x * p1[2]
- well_axis.y * camera_axis.x * p1[1])
/(well_axis.x * camera_axis.y - camera_axis.x * well_axis.y)
// Given these two equations, we now have a parameterised equation
// (x,y,z) = (mt + a, nt + b, t) = (m, n, 1)t + (a + b + 0)
//
// m = ((well_axis[2] * camera_axis[1] - camera_axis[2] * well_axis[1]))/(well_axis[1] * camera_axis[0] - camera_axis[1] * well_axis[0])
//
// n = ((well_axis[2] * camera_axis[0] - camera_axis[2] * well_axis[0]))/(well_axis[0] * camera_axis[1] - camera_axis[0] * well_axis[1])
//
// a = (- camera_axis[2] * well_axis[1] * p1[2] + camera_axis[0] * well_axis[1] * p1[0] + well_axis[2] * camera_axis[1] * p1[2] - well_axis[0] * camera_axis[1] * p1[0])/(well_axis[1] * camera_axis[0] - camera_axis[1] * well_axis[0])
//
// b = (- camera_axis[2] * well_axis[0] * p1[2] +camera_axis[1] * well_axis[0] * p1[1] + well_axis[2] * camera_axis[0] * p1[2] - well_axis[1] * camera_axis[0] * p1[1])/(well_axis[0] * camera_axis[1] - camera_axis[0] * well_axis[1])
*/
float m = ((well_axis[2] * camera_axis[1] - camera_axis[2] * well_axis[1]))/(well_axis[1] * camera_axis[0] - camera_axis[1] * well_axis[0]);
//
float n = ((well_axis[2] * camera_axis[0] - camera_axis[2] * well_axis[0]))/(well_axis[0] * camera_axis[1] - camera_axis[0] * well_axis[1]);
//
float a = (-camera_axis[2] * well_axis[1] * p1[2] + camera_axis[0] * well_axis[1] * p1[0] + well_axis[2] * camera_axis[1] * p1[2] - well_axis[0] * camera_axis[1] * p1[0])/(well_axis[1] * camera_axis[0] - camera_axis[1] * well_axis[0]);
//
float b = (-camera_axis[2] * well_axis[0] * p1[2] + camera_axis[1] * well_axis[0] * p1[1] + well_axis[2] * camera_axis[0] * p1[2] - well_axis[1] * camera_axis[0] * p1[1])/(well_axis[0] * camera_axis[1] - camera_axis[0] * well_axis[1]);
float t = 2;
return SbVec3f(m * t + a, n * t + b, t);
}
void setVertices(WellBore * pWell, SoVertexProperty * vertex_property, SoCamera* camera)
{
int nPoints = pWell->nPoints;
const float ribbon_width = 50.0f;
int vertex_index = 0;
int face_index = 0;
int max_to_draw = nPoints;
vertex_property->vertex.deleteValues(max_to_draw);
SbVec3f on_well0x = pWell->points[1];
SbVec3f in_space0x = getOuterPoint(pWell->points[0], on_well0x, ribbon_width, camera);
for (int i = 0; i < max_to_draw - 1; ++i)
{
SbVec3f on_well0 = pWell->points[i];
SbVec3f on_well1 = pWell->points[i + 1];
SbVec3f in_space1 = getOuterPoint(on_well0, on_well1, ribbon_width, camera);
vertex_property->vertex.set1Value(vertex_index + 0, in_space0x);
vertex_property->vertex.set1Value(vertex_index + 1, on_well0x);
vertex_property->vertex.set1Value(vertex_index + 2, on_well1);
vertex_property->vertex.set1Value(vertex_index + 3, in_space0x);
vertex_property->vertex.set1Value(vertex_index + 4, in_space1);
vertex_index += 5;
on_well0x = on_well1;
in_space0x = in_space1;
}
}
void cameraDebug(SoXtViewer * myViewer, WellBore* pWell)
{
SoCamera* camera = myViewer->getCamera();
SbVec3f camera_position = camera->position.getValue();
//std::cout << camera_position[0] << " " << camera_position[1] << " " << camera_position[2] << std::endl;
SbVec3f axis;
float angle;
SoSFRotation camera_rotation = camera->orientation;
camera_rotation.getValue(axis, angle);
//std::cout << axis[0] << " " << axis[1] << " " << axis[2] << ":" << angle << std::endl;
SoNode* node = SoNode::getByName(SbName("points"));
SbString str;
SoVertexProperty* vertices = static_cast<SoVertexProperty*>(static_cast<SoVertexShape*>(node)->vertexProperty.getValue());
//std::cout << vertices->vertex.getNum() << str << std::endl;
setVertices(pWell, vertices, camera);
}