下面代码的目的是定义一个可自我管理的多边形类,它由三角形对象组成,由点对象组成。
用三角形构建多边形表明多边形中的所有三角形都是连通的,更确切地说,每个三角形与之前的三角形相关。因此,我决定在三角形类中创建3个点对象,并且在引用前者和需要时指向3个点对象指针,指向另一个三角形的点。
但是我一直坚持下面的观点 - 点对象指针似乎没有指向有效的目标,尽管它们被正确地分配给三角形类的构造函数中的地址。
- 头文件 -
struct Point {
float X, Y;
Point( const float x, const float y );
Point operator+ ( Point &p );
void set( const float x, const float y );
};
class Triangle {
Point point_a_, point_b_, point_c_;
float distance_ab_, distance_bc_,
distance_ac_, area_;
void calculateArea();
void calculateDistance( );
protected:
Point *point_a_ptr_, *point_b_ptr_, *point_c_ptr_;
public:
Triangle( Point a, Point b, Point c );
void setDimensions( Point a, Point b, Point c );
float getArea() const;
float getDistance( const short index ) const;
void varPoint( const short index, Point* point );
void varPoint( const short index, Point point );
Point varPoint( const short index ) const;
friend class Polygon;
};
class Polygon {
std::vector<Triangle> triangles_;
int edges_;
public:
Polygon( const int edges );
Triangle getTriangle( const int index ) const;
void varPoint( const int index, Point point );
Point varPoint( const int index ) const;
void varEdges( const int edges );
short varEdges() const;
};
-cpp file -
Point::Point( const float x = 0, const float y = 0 ) {
X = x;
Y = y;
}
void Point::set( const float x, const float y ) {
X = x;
Y = y;
}
Point Point::operator+ ( Point &p ) {
Point calculated_point;
calculated_point.X = X + p.X;
calculated_point.Y = Y + p.Y;
return calculated_point;
}
Triangle::Triangle( Point a = Point( 0, 0 ),
Point b = Point( 0, 0 ),
Point c = Point( 0, 0 ) ) {
point_a_.set( 0, 0 );//speculation
point_b_.set( 100, 0 );//speculation
point_c_.set( 100, 200 );//speculation
point_a_ptr_ = &point_a_;
point_b_ptr_ = &point_b_;
point_c_ptr_ = &point_c_;
this->setDimensions( a, b, c );
}
void Triangle::calculateArea() {
distance_bc_ = ::distance( point_b_, point_c_ );
distance_ac_ = ::distance( point_c_, point_a_ );
distance_ab_ = ::distance( point_a_, point_b_ );
float p = ( distance_ab_ +
distance_bc_ +
distance_ac_ ) / 2.0;
area_ = sqrt( p * ( p - distance_ab_ ) *
( p - distance_bc_ ) *
( p - distance_ac_ ) );
return;
}
float Triangle::getDistance( const short index ) const {
float distance = 0;
switch( index ) {
case 0: distance = distance_ab_;
break;
case 1: distance = distance_bc_;
break;
case 2: distance = distance_ac_;
break;
default: break;
}
return distance;
}
void Triangle::setDimensions( Point a, Point b, Point c ) {
*point_a_ptr_ = a;
*point_b_ptr_ = b;
*point_c_ptr_ = c;
this->calculateArea();
}
float Triangle::getArea() const {
return area_;
}
Point Triangle::varPoint( const short index ) const {
Point return_point( 0, 0 );
switch( index ) {
case 0: return_point = *point_a_ptr_;
break;
case 1: return_point = *point_b_ptr_;
break;
case 2: return_point = *point_c_ptr_;
break;
default: break;
}
return return_point;
}
void Triangle::varPoint( const short index, Point point ) {
switch( index ) {
case 0: point_a_ = point;
break;
case 1: point_b_ = point;
break;
case 2: point_c_ = point;
break;
default: break;
}
return ;
}
void Triangle::varPoint( const short index, Point* point ) {
switch( index ) {
case 0: point_a_ptr_ = point;
break;
case 1: point_b_ptr_ = point;
break;
case 2: point_c_ptr_ = point;
break;
default: break;
}
return ;
}
Polygon::Polygon( const int edges = 3 ) {
edges_ = 0;
this->varEdges( edges );
}
Triangle Polygon::getTriangle( const int index ) const {
if( index < 0 || index >= triangles_.size() ) return Triangle();
return triangles_[index];
}
void Polygon::varEdges( const int edges ) {
if( edges < 3 || edges == edges_ ) return;
triangles_.assign( edges - 2, Triangle( Point( 0, 0 ), Point( 30, 0 ), Point( 30, 15 ) ) );
edges_ = edges;
return ;
}
short Polygon::varEdges() const {
return edges_;
}
void Polygon::varPoint( const int index, Point point ) {
if( index > edges_ - 1 ) return;
if( index < edges_ - 2 )
triangles_[index].varPoint( 0, point );
else
triangles_[triangles_.size() - 1].varPoint(edges_ - index, point);
return ;
}
Point Polygon::varPoint( const int index ) const {
Point return_point( 0, 0 );
if( index < 0 || index > edges_ - 1 ) return return_point;
if( index < edges_ - 2 )
return_point = triangles_[index].varPoint(0);
else
return_point = triangles_[triangles_.size() - 1].varPoint(edges_ - index);
return return_point;
}
此外,如果我改变三角形的点mutator函数来修改指针所引用的对象,如下所示(和原始意图一样),程序崩溃。
void Triangle::varPoint( const short index, Point point ) {
switch( index ) {
case 0: *point_a_ptr_ = point;
break;
case 1: *point_b_ptr_ = point;
break;
case 2: *point_c_ptr_ = point;
break;
default: break;
}
return ;
}
这就是为什么我总结指针必须指向一个无效的目标。
总而言之,设置三角形的点要么什么都不做(以后访问时,点为0,0)或者使程序崩溃(当使用对象指针时)。如果省略指针,则正确设置并返回点的值。使用多边形操作的代码如下所示:
Polygon polygon;
polygon.varEdges(4);
polygon.varPoint( 0, 0, 0 );
polygon.varPoint( 1, 400, 200 );
polygon.varPoint( 2, 400, 300 );
polygon.varPoint( 3, 300, 400 );
glBegin( GL_POLYGON );
glColor4f( red_/255.0, green_/255.0, blue_/255.0, alpha_ );
for( int i = 0; i < polygon.varEdges(); i++ )
glVertex2f( polygon.varPoint(i).X, polygon.varPoint(i).Y );
glEnd();
我无法弄清楚错误的位置。如果帖子过于冗长,请道歉。