/* Copyright (c) 1997-2005
   Ewgenij Gawrilow, Michael Joswig (Technische Universitaet Berlin, Germany)
   http://www.math.tu-berlin.de/polymake,  mailto:polymake@math.tu-berlin.de

   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, or (at your option) any
   later version: http://www.gnu.org/licenses/gpl.txt.

   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.
*/

#ident "$Project: polymake $$Id: 600-cell.cc,v 1.18 2005/12/06 20:04:26 gawrilow Exp $"

#include <cmath>
#include <Poly.h>
#include <Vector.h>
#include <Matrix.h>
#include <vector>
#include <permutations.h>

namespace polymake { namespace polytope {

void create_600_cell(Poly& p)
{
   const double tau=2*cos(M_PI/5); // golden ratio
   const int dim=4;

   Matrix<double> Vertices(120,dim+1);
   Rows< Matrix<double> >::iterator v=rows(Vertices).begin();

   Vector<double> vertex(dim);
   // 96 vertices of the snub-24-cell s{3,4,3}
   AllPermutations<> perms(dim);
   for (AllPermutations<>::const_iterator perm=entire(perms);
	!perm.at_end(); ++perm, ++perm)  // every second permutation (including the initial one) is even
      for (int i=1; i>=-1; i-=2)
	 for (int j=1; j>=-1; j-=2)
	    for (int k=1; k>=-1; k-=2, ++v) {
	       vertex[0]=i*tau; vertex[1]=j; vertex[2]=k/tau;
	       *v= 1. | vertex.slice(*perm);
	    }

   // 8 more vertices
   for (int n=1; n<5; ++n)
      for (int i=1; i>=-1; i-=2, ++v) {
	 (*v)[0]=1;
	 (*v)[n]=2*i;
      }

   // and finally 16 vertices
   for (int i=1; i>=-1; i-=2)
      for (int j=1; j>=-1; j-=2)
	 for (int k=1; k>=-1; k-=2)
	    for (int l=1; l>=-1; l-=2, ++v) {
	       (*v)[0]=1; (*v)[1]=i; (*v)[2]=j; (*v)[3]=k; (*v)[4]=l;
	    }

   p.take("AMBIENT_DIM") << dim;
   p.take("DIM") << dim;
   p.take("VERTICES") << Vertices;
}

} }

using namespace polymake;

/** @file 600-cell
 *
 *  Produce a polymake description of the 600-cell.
 *  Cf. Coxeter, Introduction to Geometry, pp 403-404.
 *
 *  @synopsis 600-cell <file>
 *
 *  @writing  AMBIENT_DIM, DIM, VERTICES
 *
 *  @index clients Producing from scratch
 */
int main(int argc, const char *argv[])
{
   if (argc!=2) {
      cerr << "usage: " << argv[0] << " <file>" << endl;
      return 1;
   }
   try {
      Poly p(argv[1], ios::out | ios::trunc);
      polytope::create_600_cell(p);
   }
   catch (const std::exception& e) {
      cerr << e.what() << endl;
      return 1;
   }
   return 0;
}
