polygon.h 6.29 KB
/**
 * \file polygon.h
 *
 * \brief definiert alle Klassen zu Polygonen (Gruppen mehrerer Vertexe die
 *        eine Fläche bilden.
 *
 * Hier ist die Klasse polygon definiert, die die zentrale Klasse der
 * 3D-Application ist. Es werden immer Polygone dargestellt.
 *
 * \author Georg Steffers <georg@steffers.org> [gs]
 *
 * \date 16.12.2003
 *
 * \version ..2002 [gs]: erste Implementation
 * \version 16.12.2003 [gs]: <ul><li>
 *                           Beginn der Dokumentation mir Doxygen
 *                           </li><li>
 *                           Den Sutherland-Hodgman Clipping Algorithmus
 *                           eingebaut. Er scheint zu funktionieren, muss
 *                           aber noch ausgiebig getestet werden.
 *                           </li></ul>
 * \version 19.12.2003 [gs]: <ul><li>
 *                           Vergleichsoprator hinzugef&uuml;gt
 *                           </li><li>
 *                           polygon_movable von gra_app &uuml;bertragen
 *                           </li></ul>
 * \version 21.12.2003 [gs]: vorderes z-clipping eingebaut.
 */

/* 
 * Copyright (C)2003 Georg Steffers
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#ifndef __polygon_h__
#define __polygon_h__

#include "../helper/container.h"
#include "../math/Mmn.h"
#include "vertex.h"
#include "movable.h"


class polyeder;

class polygon : public container<unsigned> {
    private:
        vertex_list* vl;
        vertex center;
        vertex normal;

        polyeder* pe;
        char id[30];

    public:
        polygon() 
            : container<unsigned>(), vl(NULL), center(vertex()), 
              normal(vertex()), pe(NULL) {}
        polygon(vertex_list *const vl) 
            : container<unsigned>(), vl(vl), center(vertex()), 
              normal(vertex()), pe(NULL) {}
        polygon(const unsigned& p, vertex_list *const vl) 
            : container<unsigned>(p), vl(vl), pe(NULL) { _init_normal_(); }
        polygon(const container<unsigned>& p, vertex_list *const vl) 
            : container<unsigned>(p), vl(vl), pe(NULL) { _init_normal_(); }
        polygon(const unsigned* idxs, unsigned count, vertex_list *const vl) 
            : container<unsigned>(idxs, count), vl(vl), 
              pe(NULL) { _init_normal_(); }
        polygon(const polygon& p) 
            : container<unsigned>(p), vl(p.vl), 
              center(p.center), normal(p.normal), pe(p.pe) { strncpy(id, p.id, 29); }
        ~polygon() {}

        virtual void _init_normal_();

        virtual bool operator==(const polygon& p) const {
           if(this->container<unsigned>::operator==((container<unsigned>)p)&&
              center==p.center &&
              normal==p.normal)
              return true;

           return false;
        }

        void set_id(const char* i) { strncpy(id, i, 29); }
        const char* get_id(void) const { return id; }

        virtual polygon clip_2d(const polygon& p) const;
        virtual polygon clip_front_z(double min_Z) const;

        virtual const polygon& operator=(const polygon& p) {
            if(this==&p)
                return *this;

            container<unsigned>::operator=(p);
            vl=p.vl;
            center=p.center;
            normal=p.normal;
            pe=p.pe;
            strncpy(id, p.id, 29);

            return *this;
        }
        virtual void set_vertex_list(vertex_list *const vl) {
            this->vl=vl;
            // dachte ich zuerst, aber eigentlich sollte alles richtig
            // gesetzt sein, da sich ja die indizies in der neuen Vertexliste
            // nicht aender sondern nur die Adressen!
            //if(normal==0 || center==0)
            //    _init_normal_();
        }
        virtual void set_polyeder(polyeder *const pe) {
           this->pe=pe;
        }
        virtual const polyeder& get_polyeder(void) {
           return *pe;
        }
        virtual const vertex& operator[](unsigned index) const {
            return (*vl)[content[index]];
        }
        virtual vertex& operator[](unsigned index) {
            return (*vl)[content[index]];
        }

        virtual unsigned vl_idx(unsigned index) {
           return content[index];
        }

        /*
         * Ich sollte den Normalenvektor aus der Vertexliste nehmen und
         * bei bedarf neu berechnen oder aber die transformation für 
         * normalenvektoren benutzen wenn ich ihn transformiere.
         */
        virtual vertex const& center_p(void) { 
           return center;
        }

        virtual vertex const& normal_p(void) const { 
           return normal; 
        }

        virtual void transform(const Mmn<double>&, int=0);
        virtual void transform_normal(const Mmn<double>&, int=0);
        virtual void reset(void);
        virtual void project_2d(double lcx, double sw, double sh, 
                                double ph_ar, double sy=1, int p=0);
};

class polygon_movable : public polygon, public movable {
   public:
      polygon_movable() : polygon(), movable() {}
      polygon_movable(vertex_list *const vl) :
         polygon(vl) {}
      polygon_movable(const unsigned& p, vertex_list *const vl) :
         polygon(p, vl) {}
      polygon_movable(const unsigned* idxs, unsigned count, 
                      vertex_list *const vl) :
         polygon(idxs, count, vl) {}
      polygon_movable(const polygon& p) :
         polygon(p) {}

      void transform(int transstage) {
         polygon::transform(t_mat, transstage);
         movable::transform(transstage);
      }

      void transform_normal(int p) {
          polygon::transform_normal(t_mat, p);
      }

      void reset(void) {
         polygon::reset();
         movable::reset(); 
      }
};


#endif // __polygon_h__