#!/usr/bin/perl -w

use strict;
use Math::Trig;
use Math::Vector::Real;
use IO::File;
use Data::Dumper;
use constant tau => pi*2;

print <<END;
// -*- C -*-
// *** AUTOGENERATED - DO NOT EDIT ***
END

my $ellipse = 20;
my $circle = 6;
my $xscale = 2;
my $N = 30; # around ellipse
my $M = 20; # around each circle

our @ellipse = map {
    my $theta = tau * $_ / $N;
    V( cos($theta) * $ellipse * $xscale, sin($theta) * $ellipse, 0 )
} 0..($N-1);

#print Dumper(\@ellipse);

our @alongs = map {
    my $i = $_;
    $ellipse[ ($i+1) % $N ] - $ellipse[ ($i-1) % $N];
} 0..($N-1);

our @circles = map {
    my $i = $_;
    my $centre = $ellipse[$i];
    my $axis = $alongs[$i]->versor();
    my $rad0 = $axis x V(0,0,1);
    my $rad1 = $rad0 x $axis;
    [ map {
	my $theta = tau * $_ / $M;
	$centre + $circle * ($rad0 * cos($theta) + $rad1 * sin($theta));
    } 0..($M-1) ];
} 0..($N-1);

sub torusy () {
    print "module Torusy(){ polyhedron(points=[";
    my $ptix = 0;
    my @cirpt;
    foreach my $i (0..$N-1) {
	foreach my $j (0..$M-1) {
	    print "," if $ptix;
	    print "\n";
	    print "    [ ", (join ", ", @{ $circles[$i][$j] }), " ]";
	    $cirpt[$i][$j] = $ptix++;
	}
    }
    print "\n  ],\n";

    print "  faces=[";
    foreach my $i (0..$N-1) {
	my $i2 = ($i+1) % $N;
	foreach my $j (0..$M-1) {
	    my $j2 = ($j+1) % $M;
	    print "," if $i || $j;
	    print "\n";
	    print "   [ ", (join ", ",
			    $cirpt[ $i  ][ $j  ],
			    $cirpt[ $i  ][ $j2 ],
			    $cirpt[ $i2 ][ $j  ],
			   ), " ],";
	    print "   [ ", (join ", ",
			    $cirpt[ $i  ][ $j2 ],
			    $cirpt[ $i2 ][ $j2 ],
			    $cirpt[ $i2 ][ $j  ],
			   ), " ]";
	}
    }
    print "\n  ]);\n}\n";
}

torusy();

while (<DATA>) { print };

STDOUT->error and die $!;
STDOUT->flush or die $!;

__DATA__
Torusy();
