⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sphere_geometry_ogl.h

📁 CGAL is a collaborative effort of several sites in Europe and Israel. The goal is to make the most i
💻 H
📖 第 1 页 / 共 2 页
字号:
// Copyright (c) 1997-2002  Max-Planck-Institute Saarbruecken (Germany).// All rights reserved.//// This file is part of CGAL (www.cgal.org); you may redistribute it under// the terms of the Q Public License version 1.0.// See the file LICENSE.QPL distributed with CGAL.//// Licensees holding a valid commercial license may use this file in// accordance with the commercial license agreement provided with the software.//// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.//// $Source: /CVSROOT/CGAL/Packages/Nef_S2/include/CGAL/Nef_S2/Sphere_geometry_OGL.h,v $// $Revision: 1.20.2.3 $ $Date: 2004/12/17 15:03:05 $// $Name:  $//// Author(s)     : Michael Seel  <seel@mpi-sb.mpg.de>#ifndef CGAL_SPHERE_GEOMETRY_OGL_H#define CGAL_SPHERE_GEOMETRY_OGL_H#include <CGAL/Nef_S2/OGL_base_object.h>#include <CGAL/Simple_cartesian.h>#include <CGAL/Nef_S2/Sphere_geometry.h>#include <CGAL/Nef_S2/SM_triangulator.h>#include <CGAL/IO/Color.h>#include <qgl.h>#include <cmath>#include <cstdlib>#include <cstdio>#include <string>#include <vector>#undef CGAL_NEF_DEBUG#define CGAL_NEF_DEBUG 151#include <CGAL/Nef_2/debug.h>#define LGREY CGAL::Color(170,170,200)#define DGREY CGAL::Color(30,30,50)CGAL_BEGIN_NAMESPACEnamespace OGL {struct Gen_object {  Gen_object() {}  virtual ~Gen_object() {}  virtual void draw() const {}  virtual Gen_object* clone() const { return 0; }  virtual void print() const {}};typedef CGAL::Simple_cartesian<double>      VKernel;typedef VKernel::Vector_3                   VVector;typedef VKernel::Point_3                    VPoint;typedef VKernel::Aff_transformation_3       VTrafo;typedef VKernel::Aff_transformation_3       Affine_3;typedef std::vector<VPoint>                 VSegment;typedef VKernel::Triangle_3                 DTriangle;typedef std::vector<DTriangle>              VTriangle;const double refinement_angle = 0.1;const double shrink_fac = 0.995;template <typename R>class Approximator { public:  static VPoint approximate(const CGAL::Sphere_point<R>& p) {    VVector v = convert(p-CGAL::ORIGIN);    v = v / CGAL_NTS sqrt(v*v) ; // normalize    return CGAL::ORIGIN+v;  }     static VSegment approximate(const CGAL::Sphere_segment<R>& s) {        /* we construct the rotation matrix that transfers the x-axis       into |ps_|, the z-axis into h_.orthogonal_vector() and the       y-axix into the corresponding crossproduct of the two.*/    if ( s.is_degenerate() ) {      VSegment S(1);      S[0] = approximate(s.source());      return S;    }        VVector v0 = convert(s.source()-CGAL::ORIGIN);    VVector v2 = convert(s.sphere_circle().orthogonal_vector());    VVector v1(-cross_product(v0,v2));    VVector v3 = convert(s.target()-CGAL::ORIGIN);    double v0l = CGAL_NTS sqrt(v0*v0);    double v1l = CGAL_NTS sqrt(v1*v1);    double v2l = CGAL_NTS sqrt(v2*v2);    double v3l = CGAL_NTS sqrt(v3*v3);    double cosalpha = v0*v3 / v0l / v3l;     double alpha = acos(cosalpha);    const int units_per_halfcircle = 50;    int units = int(units_per_halfcircle/CGAL_PI * alpha);    if (units == 0) ++units;    bool seg_is_short = s.is_short();    bool seg_is_halfcircle = s.is_halfcircle();    if ( seg_is_halfcircle ) units = units_per_halfcircle;    else if ( !seg_is_short ) {      units = 2*units_per_halfcircle - (units+1);    } CGAL_NEF_TRACEV(units); CGAL_NEF_TRACEV(cosalpha); CGAL_NEF_TRACEV(alpha);        v0 = v0 / v0l;    v1 = v1 / v1l;    v2 = v2 / v2l;    v3 = v3 / v3l;    VTrafo T(v0.x(),v1.x(),v2.x(),	     v0.y(),v1.y(),v2.y(),	     v0.z(),v1.z(),v2.z());    VSegment S(units+1);    for (int i=0; i<units; ++i)       S[i] = VPoint(cos(CGAL_PI*i/double(units_per_halfcircle)),		    sin(CGAL_PI*i/double(units_per_halfcircle)),		    0.0);    double sinalpha = 1 - cosalpha*cosalpha;    if (sinalpha <0) sinalpha = 0;     else             sinalpha = CGAL_NTS sqrt(sinalpha);    if ( seg_is_short )       S[units] = VPoint(cosalpha, sinalpha, 0);    else      S[units] = VPoint(cosalpha, -sinalpha, 0);    VSegment::iterator it;    for(it = S.begin(); it != S.end(); ++it) { CGAL_NEF_TRACEN(*it<<" "<<T(*it));    *it = T(*it);     } CGAL_NEF_TRACEN("");    return S;  }  static VSegment approximate(const CGAL::Sphere_circle<R>& s) {        /* we construct the rotation matrix that transfers the x-axis       into |ps_|, the z-axis into h_.orthogonal_vector() and the       y-axix into the corresponding crossproduct of the two.*/        VVector v0 = convert(s.base1());    VVector v1 = convert(s.base2());    VVector v2 = convert(s.orthogonal_vector());    double v0l = CGAL_NTS sqrt(v0*v0);    double v1l = CGAL_NTS sqrt(v1*v1);    double v2l = CGAL_NTS sqrt(v2*v2);    const int units = 100;    v0 = v0 / v0l;    v1 = v1 / v1l;    v2 = v2 / v2l;    VTrafo T(v0.x(),v1.x(),v2.x(),	     v0.y(),v1.y(),v2.y(),	     v0.z(),v1.z(),v2.z());    VSegment S(units);    for (int i=0; i<units; ++i) {      S[i] = VPoint(cos(2.0*CGAL_PI*i/double(units)),		    sin(2.0*CGAL_PI*i/double(units)),		    0.0);    }    VSegment::iterator it;    for(it = S.begin(); it != S.end(); ++it) *it = T(*it);     return S;  }/* the following operation refines a sphere triangle as a list of flat   triangles in 3d. The refinement only works for triangles that are   contained in a perfect hemisphere (no long sphere segments are   allowed as triangle segments). We split triangles along at the   midpoint of their longest side into two. */  static void refine(const DTriangle& t, VTriangle& T) {    double angle[3]; int i(0);    angle[0] = acos((t[0]-CGAL::ORIGIN)*(t[1]-CGAL::ORIGIN));    angle[1] = acos((t[1]-CGAL::ORIGIN)*(t[2]-CGAL::ORIGIN));    angle[2] = acos((t[2]-CGAL::ORIGIN)*(t[0]-CGAL::ORIGIN));    CGAL_NEF_TRACEN("refine "<<angle[0]<<" "<<angle[1]<<" "<<angle[2]);    if ( angle[1] > angle[0] ) {      if ( angle[2] > angle[1] ) i=2;      else                       i=1;    } else { // angle[0] >= angle[1]      if ( angle[2] > angle[0] ) i=2;      else                       i=0;    }    // now i references the side of maximal angle    if ( angle[i] < refinement_angle ) // refinement threshhold      { T.push_back(t); return; }    VVector v;    switch (i) {    case 0: v = (t[0]-CGAL::ORIGIN)+(t[1]-CGAL::ORIGIN); break;    case 1: v = (t[1]-CGAL::ORIGIN)+(t[2]-CGAL::ORIGIN); break;    case 2: v = (t[2]-CGAL::ORIGIN)+(t[0]-CGAL::ORIGIN); break;    }    v = v / CGAL_NTS sqrt(v*v) ; // normalize    VPoint p = CGAL::ORIGIN+v;    DTriangle t1,t2;    switch (i) {    case 0: t1=DTriangle(t[0],p,t[2]); t2=DTriangle(p,t[1],t[2]); break;    case 1: t1=DTriangle(t[1],p,t[0]); t2=DTriangle(p,t[2],t[0]); break;    case 2: t1=DTriangle(t[2],p,t[1]); t2=DTriangle(p,t[0],t[1]); break;    }    refine(t1,T);    refine(t2,T);  }  static VTriangle approximate(const CGAL::Sphere_triangle<R>& t) {    // we subdivide the triangle into a list of triangles until    // we reach a fine resolution on the surface.        VTriangle T;    DTriangle td(approximate(t.point(0)), 		 approximate(t.point(1)),		 approximate(t.point(2)));    CGAL_NEF_TRACEN("approximate " << td);    refine(td,T);    return T;  }};template <typename R>VVector convert(const CGAL::Vector_3<R>& v){ return VVector(CGAL::to_double(v.x()),                 CGAL::to_double(v.y()),                 CGAL::to_double(v.z())); }template <class R_>class Sphere_point : public VPoint, public Gen_object {  typedef R_ R;  CGAL::Sphere_point<R> p_;  CGAL::Color           c_;  unsigned              w_;public:  Sphere_point() {}  Sphere_point(const CGAL::Sphere_point<R>& p,    CGAL::Color c = CGAL::BLACK, unsigned w = 10) :     VPoint(Approximator<R>::approximate(p)), p_(p), c_(c), w_(w) {}  Sphere_point(const Sphere_point<R>& p) : VPoint(p)  { p_ = p.p_; c_ = p.c_; w_ = p.w_; }  Sphere_point<R>& operator=(const Sphere_point<R>& p)  { VPoint::operator=(p); p_ = p.p_;  c_ = p.c_; w_ = p.w_;    return *this; }  virtual ~Sphere_point() {}  const CGAL::Sphere_point<R>& original() const  { return p_; }  virtual Gen_object* clone() const   { return new Sphere_point<R>(*this); }   virtual void draw() const {     glPointSize(w_);    glColor3ub(c_.red(),c_.green(),c_.blue());    glBegin(GL_POINTS);    glNormal3d(x(),y(),z());    glVertex3d(x(),y(),z());    glEnd();  }  virtual void print() const   { std::cerr << "point " << p_; }};template <class R_>class Sphere_segment : public VSegment, public Gen_object {   typedef R_ R;  CGAL::Sphere_segment<R> s_;  CGAL::Color             c_;  unsigned                w_;public:  Sphere_segment() {}  Sphere_segment(const CGAL::Sphere_segment<R>& s,    CGAL::Color c = CGAL::BLACK, unsigned w = 2)     : VSegment(Approximator<R>::approximate(s)), s_(s), c_(c), w_(w) {}  Sphere_segment(const Sphere_segment<R>& s) : VSegment(s)  { s_ = s.s_; c_ = s.c_; w_ = s.w_; }  Sphere_segment<R>& operator=(const Sphere_segment<R>& s)  { VSegment::operator=(s); s_ = s.s_; c_ = s.c_; w_ = s.w_;    return *this; }  virtual ~Sphere_segment() {}  const CGAL::Sphere_segment<R>& original() const  { return s_; }  virtual Gen_object* clone() const   { return new Sphere_segment<R>(*this); }  virtual void draw() const  { CGAL_NEF_TRACEN("draw "<<s_);    if ( size() == 1 ) {      glPointSize(5*w_);      glColor3ub(c_.red(),c_.green(),c_.blue());      glBegin(GL_POINTS);      glNormal3d(begin()->x(),begin()->y(),begin()->z());      glVertex3d(begin()->x(),begin()->y(),begin()->z());      glEnd();    } else {      glLineWidth(w_);      glColor3ub(c_.red(),c_.green(),c_.blue());       glBegin(GL_LINE_STRIP);      VSegment::const_iterator it;      for(it = begin(); it != end(); ++it) {        glNormal3d(it->x(),it->y(),it->z());        glVertex3d(it->x(),it->y(),it->z());      }      glEnd();    }  }  virtual void print() const   { std::cerr << "segment " << s_; }};template <class R_>class Sphere_circle : public VSegment, public Gen_object {   typedef R_ R;  CGAL::Sphere_circle<R> s_;  CGAL::Color            c_;  unsigned               w_;public:  Sphere_circle() {}  Sphere_circle(const CGAL::Sphere_circle<R>& s,    CGAL::Color c = CGAL::BLACK, unsigned w = 2)     : VSegment(Approximator<R>::approximate(s)), s_(s), c_(c), w_(w) {}  Sphere_circle(const Sphere_circle<R>& s) : VSegment(s)  { s_ = s.s_; c_ = s.c_; w_ = s.w_; }  Sphere_circle<R>& operator=(const Sphere_circle<R>& s)  { VSegment::operator=(s); s_ = s.s_; c_ = s.c_; w_ = s.w_;    return *this; }  virtual ~Sphere_circle() {}  const CGAL::Sphere_circle<R>& original() const  { return s_; }  virtual Gen_object* clone() const   { return new Sphere_circle<R>(*this); }  virtual void draw() const  { CGAL_NEF_TRACEN("draw "<<s_);    glLineWidth(w_);    glColor3ub(c_.red(),c_.green(),c_.blue());     glBegin(GL_LINE_LOOP);    VSegment::const_iterator it;    for(it = begin(); it != end(); ++it) {      glNormal3d(it->x(),it->y(),it->z());      glVertex3d(it->x(),it->y(),it->z());    }    glEnd();  }  virtual void print() const   { std::cerr << "circle " << s_; }};/* The following class approximates a spherical triangle by a list   of flat triangles */template <class R_>class Sphere_triangle : public VTriangle, public Gen_object {   typedef R_ R;  CGAL::Sphere_triangle<R> t_;  CGAL::Color              c_;public:  Sphere_triangle() {}  Sphere_triangle(const CGAL::Sphere_triangle<R>& t,    CGAL::Color c = CGAL::Color(100,100,120))     : VTriangle(Approximator<R>::approximate(t)), t_(t), c_(c) {}  Sphere_triangle(const Sphere_triangle<R>& t) : VTriangle(t)  { t_ = t.t_; c_ = t.c_; }  Sphere_triangle<R>& operator=(const Sphere_triangle<R>& t)  { VTriangle::operator=(t); t_ = t.t_; c_ = t.c_; return *this; }  virtual ~Sphere_triangle() {}  const CGAL::Sphere_triangle<R>& original() const  { return t_; }  virtual Gen_object* clone() const   { return new Sphere_triangle<R>(*this); }  virtual void draw() const {     CGAL_NEF_TRACEN("draw "<<t_ << " in " << c_);    VTriangle::const_iterator it;    VPoint p;    glColorMaterial(GL_FRONT, GL_DIFFUSE);    glEnable(GL_COLOR_MATERIAL);    glColor3ub(c_.red(),c_.green(),c_.blue());    glBegin(GL_TRIANGLES);    for(it = begin(); it != end(); ++it) {      p = it->vertex(0);       glNormal3d(p.x(),p.y(),p.z()); 	//glVertex3d(p.x(),p.y(),p.z());      glVertex3d(shrink_fac*p.x(),shrink_fac*p.y(),shrink_fac*p.z());      p = it->vertex(1);       glNormal3d(p.x(),p.y(),p.z());       glVertex3d(shrink_fac*p.x(),shrink_fac*p.y(),shrink_fac*p.z());      p = it->vertex(2);       glNormal3d(p.x(),p.y(),p.z());       glVertex3d(shrink_fac*p.x(),shrink_fac*p.y(),shrink_fac*p.z());    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -