|
Hi all,
I've got a Perl program to generate spheres and other shapes in LDRAW
format, or as crude ASCII instruction steps. I wrote this to assist in
creating my 16x16 dome out of plates.
The program is free. You will need to have beginner Perl knowledge to use it.
Basically, edit the first line of the program to get the shape you want.
There are 6 built in, and you can edit the parameters to get others
including ellipsoids.
Has someone already done this that I don't know of?
Code at http://www.brickshelf.com/gallery/olsone/spheroids/spheroid.pl
(or see reply to this message where I'll post it for posterity)
Some samples at Brickshelf (wait for moderation)
http://www.brickshelf.com/cgi-bin/gallery.cgi?f=21558
Enjoy!
-Erik
|
|
|
#!perl5
# Spheroid.pl
# This program generates 1/4 of a dome or other shape
# Written by Erik Olson
# You will need to edit this sample code to get what you want:
$s = SpheroidSection::Sample(1);
# Add your desired shapes to the Sample() function or do it here like so:
# $s = new SpheroidSection(1, 4, 4, 10); # makes a 4x4 sphere section
$wantldraw = 1;
if ($wantldraw)
{
print $s->Ldraw(4);
# (black is 0, blue is 1, green is 2, red is 4, grey is 7, yellow is 14,
# white is 15)
# sand green might be 378 (dithered)
}
else
{
print $s->TextInstructions();
}
exit;
package SpheroidSection;
# Make a sample spheroid, your choices are 1 through 6
sub Sample
{
my ($x) = @_;
my ($s);
if ($x == 1) {
$s = new SpheroidSection(1, 8, 8, 20); # Sphere variation 1
} elsif ($x == 2) {
$s = new SpheroidSection(1, 8, 8, 10); # a squashed Sphere
} elsif ($x == 3) {
$s = new SpheroidSection(5, 8, 8, 20); # Cone variation 1
} elsif ($x == 4) {
$s = new SpheroidSection(5, 8, 8, 10); # low Cone
} elsif ($x == 5) {
$s = new SpheroidSection(9, 8, 8, 20); # Tent variation 1
} elsif ($x == 6) {
$s = new SpheroidSection(9, 8, 8, 10); # low tent
} else {
die "Sample object number $x not known, try 1 through 6\n";
}
return $s;
}
# For a good sphere, give height as 2.5 times width
# (Height is measured in plates)
sub new
{
my ($that, $rule, $xradius, $yradius, $height) = @_;
my $class = ref($that) || $that;
my ($self) = {};
bless $self, $class;
$self->{rule} = $rule;
$self->{xradius} = $xradius;
$self->{yradius} = $yradius;
$self->{height} = $height;
$self->Generate();
return $self;
}
# Calculate all the positions in steps[] that should be occupied by a plate
sub Generate
{
my ($self) = @_;
my ($grid, $x, $y, $z, $h);
# steps indexed by z, y, x. 0,0,0 is innermost stud of spheroid section.
my $steps = $self->{steps} = [];
for ($z = 0; $z < $self->{height}; $z++)
{
$steps->[$z] = []; # initialize array
for ($y = 0; $y<$self->{yradius}; $y++)
{
$steps->[$z]->[$y] = []; # initialize array
for ($x = 0; $x<$self->{xradius}; $x++)
{
$steps->[$z]->[$y]->[$x] = 0; # initialize cell
# determine if point is inside, using stud center
if ($self->InsideTest($self->{rule}, $x, $y, $z, $radius,
$radius, $height))
{
$steps->[$z]->[$y]->[$x] = 1;
}
}
}
}
}
# Printable ASCII instructions
# Subroutine returns a big string
# "O" marks a piece
# "*" marks a piece from previous step for guidance
# "." is no piece
sub TextInstructions
{
my ($self) = @_;
my ($a, $b) = (0,0);
my ($c);
my ($text);
# print step by step picture
for ($z = 0; $z < $self->{height}; $z++)
{
$text .= sprintf( "Step %d\n",$z+1);
for ($y = 0; $y<$self->{yradius}; $y++)
{
for ($x = 0; $x<$self->{xradius}; $x++)
{
$a = $self->{steps}->[$z]->[$y]->[$x];
$b = $self->{steps}->[$z-1]->[$y]->[$x] unless $z==0;
$c = $a ? "O" : $b ? "*" : ".";
$text .= $c;
}
$text .= "\n";
}
$text .= "\n";
}
return $text;
}
# LDRAW instruction or model file using 1x1 plates, part 3024
# Subroutine returns a big string
sub Ldraw
{
my ($self, $color) = @_;
my ($a, $b) = (0,0);
my ($c);
my ($text);
my ($imatrix) = "1 0 0 0 1 0 0 0 1";
my ($part) = "3024.DAT";
for ($z = 0; $z < $self->{height}; $z++)
{
$text .= sprintf( "0 STEP %d\n",$z+1);
for ($y = 0; $y<$self->{yradius}; $y++)
{
for ($x = 0; $x<$self->{xradius}; $x++)
{
$a = $self->{steps}->[$z]->[$y]->[$x];
if ($a)
{
$text .= sprintf("1 $color %d %d %d $imatrix $part\n",
$x*20, -$z*8, $y*20);
}
}
}
}
return $text;
}
# Various point-in-sphere rules selected by $rule parameter
#
# Rule 0 makes a spheroid
# Rule 4 makes a cone
# Rule 8 makes a "tentoid"
# The last few bits of the rule number are the stud inclusion rule
# +1 test center base of plate for inclusion
# +2 test center base of stud (top of plate) for inclusion
# +3 test center top of stud for inclusion
# +0 is the same as +1
sub InsideTest
{
my ($self, $rule, $x, $y, $z) = @_;
my ($v);
# exponent functions:
sub sq { return $_[0] * $_[0]; }
sub hy { return $_[0] ^ 0.50; }
my $zrule = ($rule & 0x3);
my $mainrule = $rule - $zrule;
my $zadd = [ 0, 0, 1, 1.64 ] -> [$zrule];
# rule 0: spheroid
if ($mainrule == 0)
{
$v = sq(($x+0.5)/$self->{xradius}) + sq(($y+0.5)/$self->{yradius}) +
sq(($z+$zadd)/$self->{height});
return $v < 1.0;
}
# rule 4: cone
elsif ($mainrule == 4)
{
$v = sq(($x+0.5)/$self->{xradius}) + sq(($y+0.5)/$self->{yradius});
return $v < sq(1.0 - ($z+$zadd)/$self->{height});
}
# rule 8: tent
elsif ($mainrule == 8)
{
$v = sq(($x+0.5)/$self->{xradius}) + sq(($y+0.5)/$self->{yradius});
return $v < sq(1.0 - sqrt( ($z+$zadd)/$self->{height}) );
}
else { die "InsideTest rule $rule not a known rule"; }
}
|
|
|
Sample ASCII instructions for 4x4x10 sphere section using plates
(must be viewed in a fixed width font!!!)
# "O" marks the stud of a plate you add in this step
# "*" marks a stud from the previous step, for guidance
# "." is nothing
Note: steps 1-4 are identical for this one - 4 plates deep, equals a brick
and a plate. You decide what pieces to use (brick, 1x2 plate etc.)
Step 1
OOOO
OOOO
OOO.
OO..
Step 2
OOOO
OOOO
OOO.
OO..
Step 3
OOOO
OOOO
OOO.
OO..
Step 4
OOOO
OOOO
OOO.
OO..
Step 5
OOOO
OOO*
OOO.
O*..
Step 6
OOO*
OOO.
OO*.
*...
Step 7
OOO.
OOO.
OO..
....
Step 8
OOO.
OO*.
O*..
....
Step 9
OO*.
OO..
*...
....
Step 10
OO..
O*..
....
....
|
|
|
In lugnet.cad.dev, Erik Olson writes:
> And now that I've used the output to build a paraboloid roof. Pictures of it
> all on my web site:
>
> http://olson.pair.com/moc/spheroid/spheroid.html
Hi Erik,
Pictures are great, but I get "Internal server error" when I try to download
spheroid.pl 8?(
ROSCO
|
|
|
"Ross Crawford" <rcrawford@csi.com> wrote in message
news:GzA4I5.JLq@lugnet.com...
> In lugnet.cad.dev, Erik Olson writes:
> > And now that I've used the output to build a paraboloid roof. Pictures of it
> > all on my web site:
> >
> > http://olson.pair.com/moc/spheroid/spheroid.html
>
> Hi Erik,
>
> Pictures are great, but I get "Internal server error" when I try to download
> spheroid.pl 8?(
It's possible the server is trying to run the Perl script instead of letting
you download it. Erik would have to change the extension, or ZIP it, or find
a way to disable the web server from trying to run that script.
Dan
|
|
|
Exactly. Darnit, I copied the file to "spheroid.txt" but the html saying
that is on my local machine only! Both extensions are really there. Try
getting spheroid.txt.
Maybe I'll just write a regular CGI for it!
http://www.olson.pair.com/moc/spheroid/spheroid.txt
In lugnet.cad.dev, Daniel Crichton writes:
> "Ross Crawford" <rcrawford@csi.com> wrote in message
> news:GzA4I5.JLq@lugnet.com...
> > In lugnet.cad.dev, Erik Olson writes:
> > > And now that I've used the output to build a paraboloid roof. Pictures of it
> > > all on my web site:
> > >
> > > http://olson.pair.com/moc/spheroid/spheroid.html
> >
> > Hi Erik,
> >
> > Pictures are great, but I get "Internal server error" when I try to download
> > spheroid.pl 8?(
>
> It's possible the server is trying to run the Perl script instead of letting
> you download it. Erik would have to change the extension, or ZIP it, or find
> a way to disable the web server from trying to run that script.
>
> Dan
|
|
|
Spheroid Generator is now a web page. With just a web browser you can get
instructions showing where to put plates to make a sphere, cone, or tent in
any size, using plates. Kind of like Mosaic Maker. I'll be working on this
more, so that it can make printable instructions, plus other features.
Yes the web version also makes Ldraw models.
Go here:
http://olson.pair.com/moc/spheroid/spheroid.cgi
-Erik
P.S. Follow up to lugnet.build.yoda because you'll need to use your Yoda
parts. (:
|
|
|
"Erik Olson" <erik@olson.pair.com> wrote in message
news:GzDJ3z.497@lugnet.com...
> Spheroid Generator is now a web page. With just a web browser you can get
> instructions showing where to put plates to make a sphere, cone, or tent in
Geometrically speaking, what exactly is a tent?
I generated an example so I have a sense of a tent being a kind of concave
cone, as opposed to be sphere being a convex cone (if that makes any sense).
Is there any relationship between tents and spheres? Looking at them, it seems
like a tent + sphere = cube.
Kerry, who hasn't studied geometry since 1973
|
|
|