Author Topic: Graph 3D beta update  (Read 15965 times)

0 Members and 2 Guests are viewing this topic.

Offline Han

  • LV3 Member (Next: 100)
  • ***
  • Posts: 62
  • Rating: +7/-0
    • View Profile
Graph 3D beta update
« on: December 18, 2013, 02:54:12 pm »
Since I cannot upload yet, here is the source. More info here: http://www.hpmuseum.org/forum/thread-95.html

Code: [Select]
// Graph 3D v2.221 (16-DEC-2013)
// by Han Duong

g3D_setdefault();
g3D_getfunc();
g3D_getsettings();
g3D_getwin();
g3D_setgrid();
g3D_getangles();
g3D_rotmatrix();
g3D_compute();
g3D_project();
g3D_draw();
g3D_keys();
xmin3D,xmax3D;
ymin3D,ymax3D;
zmin3D,zmax3D;
grid3D,zoom3D;

rotx,roty,rotz,Rx,Ry,Rz,Rot;
xc,yc,zc;
Zvals,Points2D,Point,zColor,zClip;
redraw3D=1,recompute3D=1,init3D=0;
minD,fxy="";


//----------------------------
// START FUNCTION
//----------------------------
view "Edit Function",START()
begin

  if init3D==0 then
    g3D_setdefault();
  end;
  startview(0,1);

end;

//----------------------------
// RESET FUNCTION
//----------------------------
View "Reset Plot Settings",RESET()
begin
  g3D_setdefault();
end;


//----------------------------
// Symb FUNCTION
//----------------------------
Symb()
begin
  startview(0,1);
end;

//----------------------------
// SymbSetup FUNCTION
//----------------------------
SymbSetup()
begin
  msgbox("Use X and Y as the input variables.")
end;

//----------------------------
// PlotSetup FUNCTION
//----------------------------
PlotSetup()
begin
  if init3D==0 then
    g3D_setdefault();
  end;
  g3D_getsettings();
end;

//----------------------------
// Plot FUNCTION
//----------------------------
Plot()
begin
  if init3D==0 then
    g3D_setdefault();
  end;
  g3D_draw();
end;

//----------------------------
// Numb FUNCTION
//----------------------------
Num()
begin
  local z_Values;
  if init3D==0 then
    g3D_setdefault();
  end;
  g3D_compute();
  z_Values:=Zvals .+ zc;
  editmat(Zvals);
end;

//----------------------------
// NumSetup FUNCTION
//----------------------------
NumSetup()
begin
  if init3D==0 then
    g3D_setdefault();
  end;
  g3D_setgrid();
end;


//----------------------------
// g3D_setdefault
//----------------------------
g3D_setdefault()
begin
  xmin3D:=-10; xmax3D:=10;
  ymin3D:=-10; ymax3D:=10;
  zmin3D:=-10; zmax3D:=10;
  zoom3D:=10; grid3D:=15;
  rotx:=105; roty:=0; rotz:=5;
  xc:=0; yc:=0; zc:=0;
  redraw3D:=1;
  recompute3D:=1;
  init3D:=1;
  fxy:="";
  g3D_getfunc();
end;

//----------------------------
// g3D_getfunc
//----------------------------
g3D_getfunc()
begin
  local i, ftot=0, fnew, fsel;

  for i from 0 to 9 do
    if ISCHECK(i) then
      fsel:=i; ftot:=ftot+1;
    end;
  end;

  if ftot==0 then
    msgbox("Please enter/select a function!");
    startview(0,1);
    kill;
  end;

  if ftot>1 then
    msgbox("Please select only one function!");
    startview(0,1);
    kill;
  end;

  fnew:=expr("STRING(V"+fsel+")");
  if fnew<>fxy then
    fxy:=fnew;
    recompute3D:=1;
  end;
  return(recompute3D);

end;

//----------------------------
// g3d_getsettings
//----------------------------
view "Plot Settings (all)",g3D_getsettings()
begin
  if init3D==0 then
    g3D_setdefault();
  end;
  g3D_getwin();
  g3D_getangles();
end;


//----------------------------
// g3D_getwin
//----------------------------
view "Set Viewing Window",g3D_getwin()
begin

  local xmin,xmax,ymin,ymax,zmin,zmax;
  local zoom;

  if init3D==0 then
    g3D_setdefault();
  end;

  xmin:=xmin3D; xmax:=xmax3D;
  ymin:=ymin3D; ymax:=ymax3D;
  zmin:=zmin3D; zmax:=zmax3D;
  zoom:=zoom3D;

  if input(
    {xmin,xmax,ymin,ymax,zmin,zmax,zoom},
    "Graph 3D View Window",
    {
      "Xmin=", "Xmax=",
      "Ymin=", "Ymax=",
      "Zmin=", "Zmax=",
      "Zoom factor="
    },
    {
      "Enter the value of back side of the viewing box",
      "Enter the value of front side of the viewing box",
      "Enter the value of left side of the viewing box",
      "Enter the value of right side of the viewing box",
      "Enter the value of bottom side of the viewing box",
      "Enter the value of top side of the viewing box",
      "Enter the zoom factor (must be > 0)"
    },
    {xmin3D,xmax3D,ymin3D,ymax3D,zmin3D,zmax3D,zoom3D})
  then

    if xmin>=xmax then
      msgbox("Warning: Invalid Xmin/Xmax! Setting Xmax:=Xmin+1");
      xmax:=xmin+1;
    end;

    if ymin>=ymax then
      msgbox("Warning: Invalid Ymin/Ymax! Setting Ymax:=Ymin+1");
      ymax:=ymin+1;
    end;

    if zmin>=zmax then
      msgbox("Warning: Invalid Zmin/Zmax! Setting Zmax:=Zmin+1");
      zmax:=zmin+1;
    end;

    if zoom3D<1 then
      msgbox("Warning: zoom must be > 0; reset to 10");
      zoom:=10;
    end;

    if (xmin<>xmin3D) or (xmax<>xmax3D) or
      (ymin<>ymin3D) or (ymax<>ymax3D) or
      (zmin<>zmin3D) or (zmax<>zmax3D)
    then
      recompute3D:=1;
      xmax3D:=xmax; xmin3D:=xmin;
      ymax3D:=ymax; ymin3D:=ymin;
      zmax3D:=zmax; zmin3D:=zmin;
      xc:=(xmax3D+xmin3D)/2;
      yc:=(ymax3D+ymin3D)/2;
      zc:=(zmax3D+zmin3D)/2;
    end;

    zoom3D:=zoom;


  end;


end;

//----------------------------
// g3D_setgrid
//----------------------------
view "Set Grid Size",g3D_setgrid()
begin
  local grid;

  if init3D==0 then
    g3D_setdefault();
  end;

  grid:=grid3D;
  if input(grid,"Graph 3D Grid Size","Grid Size=","Enter N for an NxN grid",grid3D) then
    if grid<1 then
      msgbox("Warning: grid size must be > 0; reset to 15");
      grid:=15;
    end;
  end;

  if grid<>grid3D then
    recompute3D:=1;
  end;

  grid3D:=grid;
end;

//----------------------------
// g3D_getangles
//----------------------------
view "Set Rotation Angles",g3D_getangles()
begin
  local rx,ry,rz;

  if init3D==0 then
    g3D_setdefault();
  end;

  rx:=rotx; ry:=roty; rz:=rotz;

  if input({rx,ry,rz},
    "Graph 3D Rotation Angles",
    { "X-angle=", "Y-angle=", "Z-angle=" },
    {
      "Enter the angle (deg) about the x-axis",
      "Enter the angle (deg) about the y-axis",
      "Enter the angel (deg) about the z-axis"
    },
    {rotx,roty,rotz})
  then
    if (rx<>rotx) or (ry<>roty) or (rz<>rotz) then
      rotx:=rx; roty:=ry; rotz:=rz;
    end;
  end;
end;

//----------------------------
// g3D_rotmatrix
//----------------------------
g3D_rotmatrix()
begin

  A:=rotx; B:=roty; C:=rotz;
  if HAngle==0 then
    A:=A*PI/180; B:=B*PI/180; C:=C*PI/180;
  end;

  Rx:=[[1.,0.,0.],[0.,COS(A),-SIN(A)],[0.,SIN(A),COS(A)]];
  Ry:=[[COS(B),0.,-SIN(B)],[0.,1.,0.],[SIN(B),0.,COS(B)]];
  Rz:=[[COS(C),-SIN(C),0.],[SIN(C),COS(C),0.],[0.,0.,1.]];
  Rot:=Rx*Ry*Rz;
  Rot(3,4):=minD;

end;

//----------------------------
// g3D_compute
//----------------------------
g3D_compute()
begin

  local i,j,dx,dy,xm,ym,func;
  local m,minZ,maxZ;

  if g3D_getfunc() then

    iferr func:=STRING(V0); then func:=""; end;
    V0:=fxy;

    if recompute3D then

      zColor:=makemat(RGB((grid3D+1-J)/grid3D*255,0,(I-1)/grid3D*255),grid3D+1,grid3D+1);
      dx:=(xmax3D-xmin3D)/grid3D;
      dy:=(ymax3D-ymin3D)/grid3D;
      xm:=xmin3D-dx; ym:=ymin3D-dy;
      Points2D:=makemat((xm+dx*I-xc,ym+dy*J-yc),grid3D+1,grid3D+1);

      // apps currently have terrible bug handling
      iferr
        Zvals:=makemat(V0(xm+dx*I,ym+dy*J)-zc,grid3D+1,grid3D+1);
      then
        recompute3D:=1;
        msgbox("Error during evaluation of function!");
        V0:=func;
        kill;
      end; // end error trap

      recompute3D:=0;

      // get longest distance from center to prevent inversion
      minZ:=min(Zvals); maxZ:=max(Zvals);
      minD:=10+(max(abs(minZ),abs(maxZ))^2+(xmax3D-xc)^2+(ymax3D-yc)^2)^(.5);

    end; // if recompute3D

    V0:=func;

  end; // if g3D_getfunc

end;


//----------------------------
// g3D_project
//----------------------------
g3D_project()
begin
  local clip;

  g3D_rotmatrix();
  dimgrob_p(G1, 320, 240);
  clip:=triangle(G1);
  triangle_p(G1, Points2D, zColor, Zvals, { "N", -160, -120, minD*zoom3D }, Rot, clip);
  blit_p(G0,G1);
end;


//----------------------------
// g3D_draw
//----------------------------
g3D_draw()
begin

  if init3D==0 then
    g3D_setdefault();
  end;

  g3D_compute();
  g3D_project();
  g3D_keys();
  freeze;

end;


//----------------------------
// g3D_draw
//----------------------------
g3D_keys()
begin
  local key,mousein, dx, dy;

  while 1 do
    key:=wait(-1);
    if TYPE(key)==6 then break; end;
    if key==-1 then break; end;

    repeat
      case
        if key==1 then roty:=(roty+5) MOD 360; end;
        if key==3 then roty:=(roty-5) MOD 360; end;
        if key==4 then kill; end;
        if key==7 then rotz:=(rotz-5) MOD 360; end;
        if key==8 then rotz:=(rotz+5) MOD 360; end;
        if key==2 then rotx:=(rotx-5) MOD 360; end;
        if key==12 then rotx:=(rotx+5) MOD 360; end;
        if key==45 then zoom3D:=max(zoom3D/1.05,.01); end;
        if key==50 then zoom3D:=zoom3D*1.05; end;
      end;
      g3D_project();
    until NOT IsKeyDown(key);

  end; // end while

end;
« Last Edit: December 18, 2013, 02:57:26 pm by Han »

Offline DJ Omnimaga

  • Clacualters are teh gr33t
  • CoT Emeritus
  • LV15 Omnimagician (Next: --)
  • *
  • Posts: 55943
  • Rating: +3154/-232
  • CodeWalrus founder & retired Omnimaga founder
    • View Profile
    • Dream of Omnimaga Music
Re: Graph 3D beta update
« Reply #1 on: December 18, 2013, 04:06:12 pm »
Heya, thanks for posting this here too. I am glad that you finally added filled polygons. What I am curious about is how we could write a program that shows the graph rotating, just to demonstrate how fast Graph 3D can be? I checked the app and it renders incredibly fast. I'm planning to create a Youtube video to showcase the capabilities of the HP PPL language.

EDIT: Nevermind, we can now rotate with arrow keys :)

By the way, although you can't upload in the downloads section yet, you can still upload files below posts on the forums. Just click EDIT then look for the upload form below your post text. :)
« Last Edit: December 18, 2013, 04:14:41 pm by DJ Omnimaga »

Offline Han

  • LV3 Member (Next: 100)
  • ***
  • Posts: 62
  • Rating: +7/-0
    • View Profile
Re: Graph 3D beta update
« Reply #2 on: January 02, 2014, 02:17:51 am »
A sneak peak of what's to come.


Offline DJ Omnimaga

  • Clacualters are teh gr33t
  • CoT Emeritus
  • LV15 Omnimagician (Next: --)
  • *
  • Posts: 55943
  • Rating: +3154/-232
  • CodeWalrus founder & retired Omnimaga founder
    • View Profile
    • Dream of Omnimaga Music
Re: Graph 3D beta update
« Reply #3 on: January 02, 2014, 09:00:11 pm »
Wow, HP definitively won't need to add 3D graphing to the calc, that's for sure, as you already did it and it's really impressive. I wonder if they could maybe pre-package this with the calc? It would be amazing (assuming they give you credits of course).
« Last Edit: January 02, 2014, 09:15:23 pm by DJ Omnimaga »

Offline Sorunome

  • Fox Fox Fox Fox Fox Fox Fox!
  • Support Staff
  • LV13 Extreme Addict (Next: 9001)
  • *************
  • Posts: 7920
  • Rating: +374/-13
  • Derpy Hooves
    • View Profile
    • My website! (You might lose the game)
Re: Graph 3D beta update
« Reply #4 on: January 04, 2014, 12:01:02 pm »
Wow, that is looking awesome, you did some great work on it!
:thumbsup:

THE GAME
Also, check out my website
If OmnomIRC is screwed up, blame me!
Click here to give me an internet!

Offline Han

  • LV3 Member (Next: 100)
  • ***
  • Posts: 62
  • Rating: +7/-0
    • View Profile
Re: Graph 3D beta update
« Reply #5 on: January 06, 2014, 07:42:58 pm »

Offline DJ Omnimaga

  • Clacualters are teh gr33t
  • CoT Emeritus
  • LV15 Omnimagician (Next: --)
  • *
  • Posts: 55943
  • Rating: +3154/-232
  • CodeWalrus founder & retired Omnimaga founder
    • View Profile
    • Dream of Omnimaga Music
Re: Graph 3D beta update
« Reply #6 on: January 06, 2014, 11:15:16 pm »
Thanks for the post. Gonna try this on the emulator soon. Have apps been fixed on calc yet? I heard horror stories before, but it was on the previous firmware.

Offline Han

  • LV3 Member (Next: 100)
  • ***
  • Posts: 62
  • Rating: +7/-0
    • View Profile
Re: Graph 3D beta update
« Reply #7 on: January 07, 2014, 02:01:15 pm »
As far as I know, apps have become quite stable since the update.

Offline DJ Omnimaga

  • Clacualters are teh gr33t
  • CoT Emeritus
  • LV15 Omnimagician (Next: --)
  • *
  • Posts: 55943
  • Rating: +3154/-232
  • CodeWalrus founder & retired Omnimaga founder
    • View Profile
    • Dream of Omnimaga Music
Re: Graph 3D beta update
« Reply #8 on: January 07, 2014, 02:41:39 pm »
Ok good to hear. By the way, the video shows a lower frame rate than the previous version. Is it due to the emulator being capped at 10 images/seconds or has rendering speed slowed down?

Offline Han

  • LV3 Member (Next: 100)
  • ***
  • Posts: 62
  • Rating: +7/-0
    • View Profile
Re: Graph 3D beta update
« Reply #9 on: January 07, 2014, 09:11:08 pm »
It is slower because I am using a different rendering method. The previous version uses TRIANGLE, which did z-clipping and perspective projection within the command. However, it did not allow alpha blending. So I ended up having to do my own projection calculations as well as render with FILLPOLY (for the alpha blending) which is much slower.
« Last Edit: January 07, 2014, 09:11:22 pm by Han »

Offline DJ Omnimaga

  • Clacualters are teh gr33t
  • CoT Emeritus
  • LV15 Omnimagician (Next: --)
  • *
  • Posts: 55943
  • Rating: +3154/-232
  • CodeWalrus founder & retired Omnimaga founder
    • View Profile
    • Dream of Omnimaga Music
Re: Graph 3D beta update
« Reply #10 on: January 07, 2014, 09:27:52 pm »
Oh right, I didn't realize that TRIANGLE lacked Alpha blending. I wish Alpha blending was extended to other commands, including BLIT, TEXTOUT and RECT.

Also how do we rotate in this version? I tried the arrow keys and they no longer let me rotate. I can zoom in/out with + and -, though.

EDIT: Nevermind, it seems that Symb and Help rotates, although it seems to behave weirdly
« Last Edit: January 07, 2014, 10:05:15 pm by DJ Omnimaga »

Offline Han

  • LV3 Member (Next: 100)
  • ***
  • Posts: 62
  • Rating: +7/-0
    • View Profile
Re: Graph 3D beta update
« Reply #11 on: January 07, 2014, 10:41:15 pm »
The direction keys rotate; it may be that your grid size is so large the rotation gets super slowed down. Imagine the default axes set up such that negative x points behind your screen, and positive x points towards you, the user. Negative y points left, and positive y points right. Positive z is up, and negative z is down. The left/right arrows rotate around the z-axis, up down rotate around the y-axis, and symb/help rotate around the x axis.

Offline XiiDraco

  • LV7 Elite (Next: 700)
  • *******
  • Posts: 513
  • Rating: +32/-5
  • Forget the numbers, just call me, Recreation.
    • View Profile
    • Black-Lark Games
Re: Graph 3D beta update
« Reply #12 on: January 08, 2014, 02:56:10 am »
Wow this is awesome!  :o They should definitely package this with the calc!

Offline Han

  • LV3 Member (Next: 100)
  • ***
  • Posts: 62
  • Rating: +7/-0
    • View Profile
Re: Graph 3D beta update
« Reply #13 on: January 09, 2014, 09:51:19 am »
Also how do we rotate in this version? I tried the arrow keys and they no longer let me rotate. I can zoom in/out with + and -, though.

EDIT: Nevermind, it seems that Symb and Help rotates, although it seems to behave weirdly

Ensure radian mode is on. It seems my attempt to account for various angle modes did not work properly.

The rotation bug was due to me setting all the angles to rotx! There's a new version up (same version number, different date) that fixes this among a few other issues.
« Last Edit: January 09, 2014, 12:04:01 pm by Han »

Offline Xeda112358

  • they/them
  • Moderator
  • LV12 Extreme Poster (Next: 5000)
  • ************
  • Posts: 4704
  • Rating: +719/-6
  • Calc-u-lator, do doo doo do do do.
    • View Profile
Re: Graph 3D beta update
« Reply #14 on: January 09, 2014, 10:15:21 am »
Wow Han, that is impressive! Do you think complex graphing would be possible, too? Since this would map a complex number to a complex number (CC) it requires 4 dimensions, so typically 3D+color is used. That would be pretty cool for complex analysis:)