Graph3D v2013.09.26 for HP Prime (updated)



#2

Below is the code for 3D graphing app. It is in its early stages. Directions:

1. Go to the apps menu, and highlight the Advanced Graphing app (do not start it; just highlight the icon).

2. Use the menu and select SAVE. You will then be given the chance to rename the app. Rename it Graph 3D -- it will add an underscore to the program name so that it is internally called Graph_3D.

3. Now press the apps menu key, and select Graph_3D and start the app.

4. Open the program editor [SHIFT] [1] and select Graph_3D (App) to edit it. Clear the entire program with [SHIFT] [ESC] and copy the following code there:

Due to the forum software not recognizing unicode, please copy the code first into a text editor, and do a search for "π" and replace it with the pi symbol. If you just copy it into your program editor on the calculator, make sure to adjust that bit.

Edit: updated 1:55PM EST

g3D_setdefault();
g3D_getfunc();
g3D_getsettings();
g3D_getwin();
g3D_getangles();
g3D_rotmatrix();
g3D_compute();
g3D_project();
g3D_draw();

export xmin3D,xmax3D;
export ymin3D,ymax3D;
export zmin3D,zmax3D;
export grid3D,zoom3D;
export rotx,roty,rotz,Rx,Ry,Rz,Rot;
export xc,yc,zc;
export Zvals,Points2D,Point;
export redraw3D,recompute3D,reproj3D,init3D;

export Graph_3D()
begin
end;

//----------------------------
// START FUNCTION
//----------------------------
view "Edit Function",START()
begin
// V1:="1/390*(X^3*Y-X*Y^3)";
// g3D_setdefault();
// msgbox("Enter function to plot into V1. Make sure that V1 is then selected.");
if init3D==0 then
g3D_setdefault();
end;
startview(0,1);
// g3D_getfunc();
end;

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

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

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

//----------------------------
// PlotSetup FUNCTION
//----------------------------
PlotSetup()
begin
// msgbox("Use VIEW and select 'Plot Settings'");
g3D_getsettings();
end;

//----------------------------
// Plot FUNCTION
//----------------------------
Plot()
begin
if ISCHECK(1)==0 then
msgbox("No function to plot! Enter a function into V1.");
startview(0,1);
else
g3D_draw();
end;
end;

//----------------------------
// Numb FUNCTION
//----------------------------
Num()
begin
if recompute3D then
g3D_compute();
end;
M0:=Zvals;
editmat(M0);
end;

//----------------------------
// NumSetup FUNCTION
//----------------------------
NumSetup()
begin
end;

//----------------------------
// g3D_setdefault
//----------------------------
g3D_setdefault()
begin
xmin3D:=-10; xmax3D:=10;
ymin3D:=-10; ymax3D:=10;
zmin3D:=-10; zmax3D:=10;
zoom3D:=10; grid3D:=14;
rotx:=0; roty:=-15; rotz:=10;
xc:=0; yc:=0; zc:=0;
redraw3D:=1;
recompute3D:=1;
reproj3D:=1;
init3D:=1;
g3D_rotmatrix();
end;

//----------------------------
// g3D_getfunc
//----------------------------
g3D_getfunc()
begin
input(V1,"Graph 3D","f(X,Y)=","Enter a function in terms of X and Y",V1);
end;

//----------------------------
// g3d_getsettings
//----------------------------
view "Plot Settings",g3D_getsettings()
begin
g3D_getwin();
g3D_getangles();
end;

//----------------------------
// g3D_getwin
//----------------------------
view "Window Settings",g3D_getwin()
begin

input(xmin3D,"Graph 3D Window","xMin=","Enter front side of viewing box",xmin3D);
input(xmax3D,"Graph 3D Window","xMax=","Enter back side of viewing box",xmax3D);
if xmin3D>=xmax3D then
msgbox("Warning: Invalid xmin/xmax!");
xmax3D:=xmin3D+1;
end;
xc:=(xmax3D+xmin3D)/2;

input(ymin3D,"Graph 3D Window","yMin=","Enter left side of viewing box",ymin3D);
input(ymax3D,"Graph 3D Window","yMax=","Enter right side of viewing box",ymax3D);
if ymin3D>=ymax3D then
msgbox("Warning: Invalid yMin/yMax!");
ymax3D:=ymin3D+1;
end;
yc:=(ymax3D+ymin3D)/2;

input(zmin3D,"Graph 3D Window","zMin=","Enter bottom side of viewing box",zmin3D);
input(zmax3D,"Graph 3D Window","zMax=","Enter left side of viewing box",zmax3D);
if zmin3D>=zmax3D then
msgbox("Warning: Invalid zMin/zMax!");
zmax3D:=zmin3D+1;
end;
zc:=(zmax3D+zmin3D)/2;

input(zoom3D,"Graph 3D Zoom Factor","Zoom=","Enter the zoom factor",zoom3D);
if zoom3D<1 then
msgbox("Warning: zoom must be > 0; reset to 10");
zoom3D:=10;
end;

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

end;

//----------------------------
// g3D_getangles
//----------------------------
view "Set Rotation Angles",g3D_getangles()
begin
input(rotx,"Graph 3D Rotation","X-angle=","Enter angle (deg) about the x-axis",rotx);
input(roty,"Graph 3D Rotation","Y-angle=","Enter angle (deg) about the y-axis",roty);
input(rotz,"Graph 3D Rotation","Z-angle=","Enter angle (deg) about the z-axis",rotz);
g3D_rotmatrix();
end;

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

A:=rotx*&#960;/180; B:=roty*&#960;/180; C:=rotz*&#960;/180;

expr("Rx:=[[1.,0.,0.],[0.,COS(A),-SIN(A)],[0.,SIN(A),COS(A)]]");
expr("Ry:=[[COS(B),0.,-SIN(B)],[0.,1.,0.],[SIN(B),0.,COS(B)]]");
expr("Rz:=[[COS(C),-SIN(C),0.],[SIN(C),COS(C),0.],[0.,0.,1.]]");
Rot:=Rx*Ry*Rz;
reproj3D:=1;

end;

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

local i,j,dx,dy;

if recompute3D then
Zvals:=[[0]];

dx:=(xmax3D-xmin3D)/grid3D;
dy:=(ymax3D-ymin3D)/grid3D;

for j from 0 to grid3D do
for i from 0 to grid3D do
X:=xmin3D+dx*i;
Y:=ymin3D+dy*j;
Z:=V1(X,Y); Zvals(j+1,i+1):=Z;
end;
end;
end;
recompute3D:=0;

end;

//----------------------------
// g3D_project
//----------------------------
g3D_project()
begin
local i,j,dx,dy,x,y;

if recompute3D then g3D_compute(); end;

if reproj3D then
Points2D:=[[0]];

dx:=(xmax3D-xmin3D)/grid3D;
dy:=(ymax3D-ymin3D)/grid3D;

for j from 0 to grid3D do
for i from 0 to grid3D do
X:=xmin3D+dx*i;
Y:=ymin3D+dy*j;

Z:=Zvals(j+1,i+1);
expr("Point:=Rot*[[X-xc],[Y-xc],[Z-xc]]");
Z:=abs(xmax3D-xc+5-Point(1,1));
X:=Point(2,1)/Z*zoom3D;
Y:=Point(3,1)/Z*zoom3D;
Points2D(j+1,i+1):=(X,Y);

end;
end;

reproj3D:=0;
end;

end;

//----------------------------
// g3D_draw
//----------------------------
g3D_draw()
begin
local i, j, x,y;

g3D_project();

for j from 0 to grid3D do
for i from 0 to grid3D do

X:=re(Points2D(j+1,i+1));
Y:=im(Points2D(j+1,i+1));

if i then
x:=re(Points2D(j+1,i));
y:=im(Points2D(j+1,i));
line(X,Y,x,y,RGB(i/grid3D*255,0,j/grid3D*255));
end;

if j then
x:=re(Points2D(j,i+1));
y:=im(Points2D(j,i+1));
line(X,Y,x,y,RGB(i/grid3D*255,0,j/grid3D*255));
end;

end;
end;

freeze;

end;
// end of code

5. Exit the program editor, and re-run Graph 3D from the apps menu.

6. Enter in a two-variable function into V1.

7. You can use the default settings (or change the settings) by pressing VIEW. You must enter in new window settings at least once (or just choose to use the default values).

8. Press [Plot] once you have adjusted the window settings.

Known issues:

The window does not "clear" the screen first before drawing. This is an easy fix once I get familiar with all the different screens. The program currently uses the current window settings from the Plot app so if you don't see anything, reset the Plot app first. Again an easy fix, but I'm working on other things at the moment.

-- Han


Edited: 28 Sept 2013, 1:33 p.m. after one or more responses were posted


#3

Very nice start :)

I hope we'll be able to rotate with the pad soon (or yet better with the touch screen but that's probably not doable from a basic program ?)

A screenshot for 5*sin(x*y)/(x*y) with default zoom and parameters :


#4

Actually, there are commands to track the "mouse" (your gestures) but I need to figure out how to capture them first. There doesn't seem to be a way to have the calculator put itself in a low power mode until a gesture interrupts this state. Right now, it appears I have to run a constant loop to track keyboard and mouse input.

Han

#5

Quote:
I hope we'll be able to rotate with the pad soon (or yet better with the touch screen but that's probably not doable from a basic program ?)

Look at the MOUSE command...

from the help:
Syntax: MOUSE[(index)]

Returns the current pointer's location.
returns: two lists of the form {#x, #y, #originalx, #originaly, #type}, one for each potential pointer.
Note, if a pointer is unused, returns an empty list
#type is: #0: New, #1: Completed, #2: Drag, #3: Stretch, #4: Rotate, #5: LongClick

MOUSE(x) returns the nth element that would be returned if MOUSE was called with no arguements or -1 if the associated pointer is not down.


Possibly Related Threads...
Thread Author Replies Views Last Post
  HP Prime finally updated! Les Koller 8 523 12-10-2013, 09:25 PM
Last Post: Les Koller
  HP-70 simulator updated Willy R. Kunz 3 305 11-26-2013, 08:20 PM
Last Post: BShoring
  Updated PPC DVD Version 2.10: HP-41 Searchable Program Files and Scannable Barcode Jake Schwartz 3 273 09-27-2013, 09:51 PM
Last Post: Olivier (Wa)
  OT: PockEmul has been updated Bill (Smithville, NJ) 0 168 08-07-2013, 03:16 PM
Last Post: Bill (Smithville, NJ)
  RPN-67 Pro updated to v1.2 Willy R. Kunz 29 1,247 06-12-2013, 04:32 PM
Last Post: Willy R. Kunz
  RPN-67 Pro updated Willy R. Kunz 8 389 05-16-2013, 05:12 AM
Last Post: Willy R. Kunz
  [41CL] Updated Manual Monte Dalrymple 1 172 05-14-2013, 10:22 PM
Last Post: Matt Kernal
  Updated HP-41 Flex-PCB replacement guide. Diego Diaz 2 217 03-12-2013, 12:36 PM
Last Post: Diego Diaz
  Updated PPC DVD Disk w/HHC2012 Materials Jake Schwartz 1 188 01-26-2013, 02:45 AM
Last Post: Walter B
  Update of Emu28 to v1.26 Christoph Giesselink 1 160 10-18-2012, 03:48 AM
Last Post: Nick_S

Forum Jump: