/*
 * Polygon.C
 *
 * Copyright (C) 1992, Christoph Streit (streit@iam.unibe.ch)
 *                     University of Berne, Switzerland
 * All rights reserved.
 *
 * This software may be freely copied, modified, and redistributed
 * provided that this copyright notice is preserved on all copies.
 *
 * You may not distribute this software, in whole or in part, as part of
 * any commercial product without the express consent of the authors.
 *
 * There is no warranty or other guarantee of fitness of this software
 * for any purpose.  It is provided solely "as is".
 *
 */

#include "Polygon.h"

implementList(VertexList, Vector);
implementList(PolygonList, PolygonPtr);

Polygon::Polygon(long size)
{
  vertices = new VertexList(size);
}

Polygon::Polygon(const Vector& p1, const Vector& p2, const Vector& p3)
{
  vertices = new VertexList(3);
  vertices->append(p1);
  vertices->append(p2); 
  vertices->append(p3);
}

Polygon::Polygon(const Vector& p1, const Vector& p2, 
		 const Vector& p3, const Vector& p4)
{
  vertices = new VertexList(4);
  vertices->append(p1);
  vertices->append(p2); 
  vertices->append(p3);
  vertices->append(p4);
}

Polygon::Polygon(const Polygon& p)
{
  vertices = new VertexList(p.numVertices());
  for (register long i=0; i<p.numVertices(); i++)
    vertices->append(p.vertices->item(i));
}

Polygon::~Polygon()
{
  delete vertices;
}

/*
 * Transform the vertices of the polygon.
 */

void Polygon::transform(const TransMatrix& tmat)
{
  for (register long i=0; i < vertices->count(); i++)
    vertices->item(i) = vertices->item(i)*tmat;
}

/*
 * Compute the normal of the polygon.
 */

const Vector& Polygon::normal() const
{
  static Vector noNormal(0,0,0);
  if (vertices->count() < 3)
    return noNormal;

  static Vector n;
  Vector p1 = vertices->item(0);
  Vector p2 = vertices->item(1);
  Vector p3 = vertices->item(vertices->count()-1);

  /*
   * Find 3 vertices and compute the cross product. If the 
   * resulting vector is not of yero length, take it as the 
   * normal of the polygon. Otherwise continue.
   */
  for (register long i=1; i < vertices->count(); i++) {
    n = (p2-p1)*(p3-p1);
    if (!n.zero()) {
      n.normalize();
      return n;
    }
    p3 = p1; p1 = p2; p2 = vertices->item((i+1)%vertices->count());
  }

  return noNormal;
}

void Polygon::addVertex(const Vector& v)
{
  vertices->append(v);
}

void Polygon::removeVertex(long index)
{
  vertices->remove(index);
}


