是否可以使用 CGAL 绘制 3d 线段?
Is it possible to draw 3d segments with CGAL?
我想画3d线段,相机可以旋转,这样可以从不同的角度观察线段。我想知道是否有办法用 CGAL 绘制它们?我知道 CGAL 不是专门用于可视化的,所以这个问题本身可能有点愚蠢。但是如果它有这个功能对我来说真的很有帮助,因为我对CGAL有一些经验。
我尝试学习OpenGL,但我不可能在短时间内掌握它。而且我也不想花太多时间去学习OpenGL,因为以后的工作中不会再用到它。
如果CGAL没有这个功能,能否请您推荐一些轻量级可以绘制3d线段的开源库?我不需要功能非常丰富但庞大的图书馆。一款易于使用且重量轻的最适合我。非常感谢!
CGAL::Basic_viewer_qt 允许在 2D/3D 中绘制点、线段和面。
您可以定义自己的查看器,继承自此 class.
按照 Marc 的建议,查看不同的 draw_XXX.h 文件,了解如何在 CGAL 中为多个查看器实现这一点。
听从Marc Glisse和gdamiand的建议,我仿照文件draw_triangulation3.h
中的classSimpleTriangulation3ViewerQt
,写了一个class,名称为SimpleSegments3ViewerQt
。它确实有效。谢谢你的建议!这是代码。
#pragma once
#include<CGAL/Qt/Basic_viewer_qt.h>
//a struct that describes 3d segment, Point is the data structure of vertex of segment.
template<typename Point>
struct mySegment3d {
Point begin;
Point end;
mySegment3d() {}
mySegment3d(Point b,Point e):begin(b),end(e){}
};
#ifdef CGAL_USE_BASIC_VIEWER
#include<CGAL/Qt/init_ogl_context.h>
//viewer for mySegment3d
//Segs3 is an array of mySegment3d which can be traveled by iterator, such as std::veector<mySegment3d>.
template<class Segs3,class point>
class SimpleSegments3ViewerQt :public CGAL::Basic_viewer_qt
{
typedef Basic_viewer_qt Base;
typedef mySegment3d<point> mySegment3d;
public:
//construct the viewer
SimpleSegments3ViewerQt(QWidget* parent,
const Segs3& seg3,
const char* title = "Basic Segs3 Viewer") :
//First draw: vertices, edges, faces, multi-color, no inverse normal
Base(parent, title, true, true, false, false, true),
s3(seg3)
{
compute_elements();
}
protected:
const Segs3& s3;
protected:
void compute_edge(const mySegment3d& seg) {
add_segment(seg.begin, seg.end, CGAL::IO::blue());
}
void compute_vertex(const mySegment3d& seg) {
add_point(seg.begin, CGAL::IO::red());
add_point(seg.end,CGAL::IO::red());
}
void compute_elements() {
clear();
for (auto itor = s3.begin(); itor != s3.end(); ++itor) {
compute_vertex(*itor);
compute_edge(*itor);
}
}
virtual void keyPressEvent(QKeyEvent* e) {
Base::keyPressEvent(e);
}
};
//draw function
template<typename Segs3,typename Point>
void draw(const Segs3& s3, const char* title = "Segs3 Basic Viewer") {
#if defined(CGAL_TEST_SUITE)
bool cgal_test_suite = true;
#else
bool cgal_test_suite = qEnvironmentVariableIsSet("CGAL_TEST_SUITE");
#endif
if (!cgal_test_suite) {
CGAL::Qt::init_ogl_context(4, 3);
int argc = 1;
const char* argv[2] = { "segs3_viewer","[=10=]" };
QApplication app(argc, const_cast<char**>(argv));
SimpleSegments3ViewerQt<Segs3,Point> mainwindow(app.activeWindow(),
s3, title);
mainwindow.show();
app.exec();
}
}
#endif
这是一个用法示例。
#include<vector>
#include<CGAL/Simple_cartesian.h>
#include"draw_segments_3.h"
typedef CGAL::Simple_cartesian<double> kernel;
typedef kernel::Point_3 Point_3;
//draw_segments3 test
int main() {
std::vector<mySegment3d<Point_3>> segs;
Point_3 p0(0, 0, 0), p1(1, 2, 3), p2(5, 3, 1), p3(3, 1, 10);
mySegment3d<Point_3> s0(p0, p1), s1(p0, p2), s2(p0, p3);
segs.emplace_back(s0);
segs.emplace_back(s1);
segs.emplace_back(s2);
draw<std::vector<mySegment3d<Point_3>>,Point_3>(segs);
}
我想画3d线段,相机可以旋转,这样可以从不同的角度观察线段。我想知道是否有办法用 CGAL 绘制它们?我知道 CGAL 不是专门用于可视化的,所以这个问题本身可能有点愚蠢。但是如果它有这个功能对我来说真的很有帮助,因为我对CGAL有一些经验。
我尝试学习OpenGL,但我不可能在短时间内掌握它。而且我也不想花太多时间去学习OpenGL,因为以后的工作中不会再用到它。
如果CGAL没有这个功能,能否请您推荐一些轻量级可以绘制3d线段的开源库?我不需要功能非常丰富但庞大的图书馆。一款易于使用且重量轻的最适合我。非常感谢!
CGAL::Basic_viewer_qt 允许在 2D/3D 中绘制点、线段和面。 您可以定义自己的查看器,继承自此 class.
按照 Marc 的建议,查看不同的 draw_XXX.h 文件,了解如何在 CGAL 中为多个查看器实现这一点。
听从Marc Glisse和gdamiand的建议,我仿照文件draw_triangulation3.h
中的classSimpleTriangulation3ViewerQt
,写了一个class,名称为SimpleSegments3ViewerQt
。它确实有效。谢谢你的建议!这是代码。
#pragma once
#include<CGAL/Qt/Basic_viewer_qt.h>
//a struct that describes 3d segment, Point is the data structure of vertex of segment.
template<typename Point>
struct mySegment3d {
Point begin;
Point end;
mySegment3d() {}
mySegment3d(Point b,Point e):begin(b),end(e){}
};
#ifdef CGAL_USE_BASIC_VIEWER
#include<CGAL/Qt/init_ogl_context.h>
//viewer for mySegment3d
//Segs3 is an array of mySegment3d which can be traveled by iterator, such as std::veector<mySegment3d>.
template<class Segs3,class point>
class SimpleSegments3ViewerQt :public CGAL::Basic_viewer_qt
{
typedef Basic_viewer_qt Base;
typedef mySegment3d<point> mySegment3d;
public:
//construct the viewer
SimpleSegments3ViewerQt(QWidget* parent,
const Segs3& seg3,
const char* title = "Basic Segs3 Viewer") :
//First draw: vertices, edges, faces, multi-color, no inverse normal
Base(parent, title, true, true, false, false, true),
s3(seg3)
{
compute_elements();
}
protected:
const Segs3& s3;
protected:
void compute_edge(const mySegment3d& seg) {
add_segment(seg.begin, seg.end, CGAL::IO::blue());
}
void compute_vertex(const mySegment3d& seg) {
add_point(seg.begin, CGAL::IO::red());
add_point(seg.end,CGAL::IO::red());
}
void compute_elements() {
clear();
for (auto itor = s3.begin(); itor != s3.end(); ++itor) {
compute_vertex(*itor);
compute_edge(*itor);
}
}
virtual void keyPressEvent(QKeyEvent* e) {
Base::keyPressEvent(e);
}
};
//draw function
template<typename Segs3,typename Point>
void draw(const Segs3& s3, const char* title = "Segs3 Basic Viewer") {
#if defined(CGAL_TEST_SUITE)
bool cgal_test_suite = true;
#else
bool cgal_test_suite = qEnvironmentVariableIsSet("CGAL_TEST_SUITE");
#endif
if (!cgal_test_suite) {
CGAL::Qt::init_ogl_context(4, 3);
int argc = 1;
const char* argv[2] = { "segs3_viewer","[=10=]" };
QApplication app(argc, const_cast<char**>(argv));
SimpleSegments3ViewerQt<Segs3,Point> mainwindow(app.activeWindow(),
s3, title);
mainwindow.show();
app.exec();
}
}
#endif
这是一个用法示例。
#include<vector>
#include<CGAL/Simple_cartesian.h>
#include"draw_segments_3.h"
typedef CGAL::Simple_cartesian<double> kernel;
typedef kernel::Point_3 Point_3;
//draw_segments3 test
int main() {
std::vector<mySegment3d<Point_3>> segs;
Point_3 p0(0, 0, 0), p1(1, 2, 3), p2(5, 3, 1), p3(3, 1, 10);
mySegment3d<Point_3> s0(p0, p1), s1(p0, p2), s2(p0, p3);
segs.emplace_back(s0);
segs.emplace_back(s1);
segs.emplace_back(s2);
draw<std::vector<mySegment3d<Point_3>>,Point_3>(segs);
}