Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

Re: rotating cube.

by rjt (Deacon)
on Jul 08, 2013 at 04:04 UTC ( #1043030=note: print w/ replies, xml ) Need Help??


in reply to rotating cube.

For an in-depth look at the math (with some other simple formulae you can experiment with), take a look at 3D Projection at Wikipedia.

Back to Perl, if you want to simply plot a non-moving cube (or pre-render a series of video frames) without fancy shading, texture mapping, etc., GD or Image::Magick will do just fine. For more realistic 2D renders or any sort of "live" 3D animation of a rotating cube, have a look at SDL::OpenGL. There is also POGL (OpenGL), but it looks to have gone stale. I am not sure how good SDL::OpenGL is, for that matter.

Honorable mention for 2D work at least would be PDL::Graphics::OpenGL for an OpenGL plugin to the Perl Data Language, but PDL is probably pretty far from what you need to draw a simple cube.


Comment on Re: rotating cube.
Download Code
Re^2: rotating cube.
by Anonymous Monk on Jul 09, 2013 at 08:00 UTC

    Thank you for replying. Just for the record: You're saying that if i work with the GD module or Image::Magick(i'm not familiar with that module) there is no other way than to manually convert 3d coordinates to 2d. If i want support for handling 3d coordinates i need a completely new module like SDL::OpenGL. Is this correct? Much obliged.

      Correct. Both libraries are fundamentally 2D with no 3D support, besides some typical "3D Graphing" features. You should be able to figure out simple shapes easily enough. Beyond that, especially once you get into overlapping vertices in the visual projection, figuring out what is visible and drawing in a sensible order can get hairy, and a pure-ish Perl solution would best be measured in seconds per frame, not the inverse.

      So, my advice would be, either keep it very simple, and learn some fun math, or embrace a much bigger library from the start. Whatever you decide, you might also try out something like Blender (free 3D software) to rapidly prototype your models and boost your visual comprehension. Good luck! Come back and post your creation.

        I'll show you what i've been doing. I managed to make my program work, but i'm not gonna continue with the same way. So here's the code, i hope you're not going to laugh. Let's call this a robust attempt:

        use GD; use constant PI => 4 * atan2(1, 1); $ima = new GD::Image(800,800); $black = $ima->colorAllocate(0,0,0); $green=$ima->colorAllocate(0,255,0); $ima->setThickness(3); $data = $ima->gifanimbegin(1,0); $im = new GD::Image(800,800); $black = $im->colorAllocate(0,0,0); $green=$im->colorAllocate(0,255,0); $white=$im->colorAllocate(0,0,0); $im->setThickness(3); @een=(360,360,80); @twee=(440,360,80); @drie=(440,360,0); @vier=(360,360,0); $x1 =$een[0] + sqrt($een[2]**2/2); $y1=$een[1] - sqrt($een[2]**2/2); $x2 =$twee[0] + sqrt($twee[2]**2/2); $y2=$twee[1] - sqrt($twee[2]**2/2); $x3 =$drie[0] + sqrt($drie[2]**2/2); $y3=$drie[1] - sqrt($drie[2]**2/2); $x4 =$vier[0] + sqrt($vier[2]**2/2); $y4=$vier[1] - sqrt($vier[2]**2/2); $xx1=$x1; $xx2=$x2; $xx3=$x3; $xx4=$x4; $yy1=$y1+80; $yy2=$y2+80; $yy3=$y3+80; $yy4=$y4+80; $im->line($x1,$y1,$x2,$y2,$green); $im->line($x2,$y2,$x3,$y3,$green); $im->line($x3,$y3,$x4,$y4,$green); $im->line($x4,$y4,$x1,$y1,$green); $im->line($xx1,$yy1,$xx2,$yy2,$green); $im->line($xx2,$yy2,$xx3,$yy3,$green); $im->line($xx3,$yy3,$xx4,$yy4,$green); $im->line($xx4,$yy4,$xx1,$yy1,$green); $im->line($x1,$y1,$xx1,$yy1,$green); $im->line($x2,$y2,$xx2,$yy2,$green); $im->line($x3,$y3,$xx3,$yy3,$green); $im->line($x4,$y4,$xx4,$yy4,$green); $data.=$im->gifanimadd(0,0,0,1); $teller = 0; again: for($x=PI/4;$x<=PI/2;$x+=PI/8){ $img = new GD::Image(800,800); $black = $img->colorAllocate(0,0,0); $green=$img->colorAllocate(0,255,0); $white=$img->colorAllocate(0,0,0); $img->setThickness(3); @een=(360,360,80); @twee=(440,360,80); @drie=(440,360,0); @vier=(360,360,0); $straal = sqrt((40*40)+(40*40)); $yh = $straal * sin($x); $hoogte =$yh-40; $xv = sqrt($straal**2-$yh**2); $xver = 40 - $xv; $een[0]+=$xver; $een[2]+=$hoogte; $twee[0]+=$hoogte; $twee[2]-=$xver; $drie[0]-=$xver; $drie[2]-=$hoogte; $vier[0]-=$hoogte; $vier[2]+=$xver; if($een[2]>0){ $x1 =$een[0] + sqrt($een[2]**2/2); $y1=$een[1] - sqrt($een[2]**2/2);} else{ $x1 =$een[0] - sqrt($een[2]**2/2); $y1=$een[1] + sqrt($een[2]**2/2);} if($twee[2]>0){ $x2 =$twee[0] + sqrt($twee[2]**2/2); $y2=$twee[1] - sqrt($twee[2]**2/2);} else{ $x2 =$twee[0] - sqrt($twee[2]**2/2); $y2=$twee[1] + sqrt($twee[2]**2/2);} if($drie[2]>0){ $x3 =$drie[0] + sqrt($drie[2]**2/2); $y3=$drie[1] - sqrt($drie[2]**2/2);} else{ $x3 =$drie[0] - sqrt($drie[2]**2/2); $y3=$drie[1] + sqrt($drie[2]**2/2);} if($vier[2]>0){ $x4 =$vier[0] + sqrt($vier[2]**2/2); $y4=$vier[1] - sqrt($vier[2]**2/2);} else{ $x4 =$vier[0] - sqrt($vier[2]**2/2); $y4=$vier[1] + sqrt($vier[2]**2/2);} $xx1=$x1; $xx2=$x2; $xx3=$x3; $xx4=$x4; $yy1=$y1+80; $yy2=$y2+80; $yy3=$y3+80; $yy4=$y4+80; $img->line($x1,$y1,$x2,$y2,$green); $img->line($x2,$y2,$x3,$y3,$green); $img->line($x3,$y3,$x4,$y4,$green); $img->line($x4,$y4,$x1,$y1,$green); $img->line($xx1,$yy1,$xx2,$yy2,$green); $img->line($xx2,$yy2,$xx3,$yy3,$green); $img->line($xx3,$yy3,$xx4,$yy4,$green); $img->line($xx4,$yy4,$xx1,$yy1,$green); $img->line($x1,$y1,$xx1,$yy1,$green); $img->line($x2,$y2,$xx2,$yy2,$green); $img->line($x3,$y3,$xx3,$yy3,$green); $img->line($x4,$y4,$xx4,$yy4,$green); $data.=$img->gifanimadd(0,0,0,1); } $img = new GD::Image(800,800); $black = $img->colorAllocate(0,0,0); $green=$img->colorAllocate(0,255,0); $white=$img->colorAllocate(0,0,0); $img->setThickness(3); @een=(360,360,80); @twee=(440,360,80); @drie=(440,360,0); @vier=(360,360,0); $yh = $straal * sin((PI/8)*5); $hoogte =$yh-40; $xv = sqrt($straal**2-$yh**2); $xver = 40 + $xv; $een[0]+=$xver; $een[2]+=$hoogte; $twee[0]+=$hoogte; $twee[2]-=$xver; $drie[0]-=$xver; $drie[2]-=$hoogte; $vier[0]-=$hoogte; $vier[2]+=$xver; if($een[2]>0){ $x1 =$een[0] + sqrt($een[2]**2/2); $y1=$een[1] - sqrt($een[2]**2/2);} else{ $x1 =$een[0] - sqrt($een[2]**2/2); $y1=$een[1] + sqrt($een[2]**2/2);} if($twee[2]>0){ $x2 =$twee[0] + sqrt($twee[2]**2/2); $y2=$twee[1] - sqrt($twee[2]**2/2);} else{ $x2 =$twee[0] - sqrt($twee[2]**2/2); $y2=$twee[1] + sqrt($twee[2]**2/2);} if($drie[2]>0){ $x3 =$drie[0] + sqrt($drie[2]**2/2); $y3=$drie[1] - sqrt($drie[2]**2/2);} else{ $x3 =$drie[0] - sqrt($drie[2]**2/2); $y3=$drie[1] + sqrt($drie[2]**2/2);} if($vier[2]>0){ $x4 =$vier[0] + sqrt($vier[2]**2/2); $y4=$vier[1] - sqrt($vier[2]**2/2);} else{ $x4 =$vier[0] - sqrt($vier[2]**2/2); $y4=$vier[1] + sqrt($vier[2]**2/2);} $xx1=$x1; $xx2=$x2; $xx3=$x3; $xx4=$x4; $yy1=$y1+80; $yy2=$y2+80; $yy3=$y3+80; $yy4=$y4+80; $img->line($x1,$y1,$x2,$y2,$green); $img->line($x2,$y2,$x3,$y3,$green); $img->line($x3,$y3,$x4,$y4,$green); $img->line($x4,$y4,$x1,$y1,$green); $img->line($xx1,$yy1,$xx2,$yy2,$green); $img->line($xx2,$yy2,$xx3,$yy3,$green); $img->line($xx3,$yy3,$xx4,$yy4,$green); $img->line($xx4,$yy4,$xx1,$yy1,$green); $img->line($x1,$y1,$xx1,$yy1,$green); $img->line($x2,$y2,$xx2,$yy2,$green); $img->line($x3,$y3,$xx3,$yy3,$green); $img->line($x4,$y4,$xx4,$yy4,$green); $data.=$img->gifanimadd(0,0,0,1); if($teller<20){ $teller++; goto again;} $data.=$im->gifanimend; binmode STDOUT; print $data;

        have a good day

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1043030]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chilling in the Monastery: (10)
As of 2014-10-20 22:14 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    For retirement, I am banking on:










    Results (92 votes), past polls