Ejemplo: Selector del ViewPoint

Este ejemplo, usa elementos tomados de  los programas:  "RealTimePlot dialog" de  Tom Wickham-Jones,  "A Modal Input Dialog"  y "A Button Palette"  en J/Link User Guide de Tood Gayley, para definir un procedimiento que usando "en vivo" un gráfico en tres dimensiones, permita rotarlo apropiadamente a fin de buscar el valor para la opción ViewPoint,  que produzca el gráfico en la orientación deseada.

Definición de procedimientos.

Needs["JLink`"]

UseFrontEndForRendering=False;

createWindow[] :=
	Module[{frame, sliderHor, sliderVer, listener, listen, okButton, tok},
		InstallJava[];
		frame = JavaNew["com.wolfram.jlink.MathFrame", "Selector del ViewPoint"];
		drawArea = JavaNew["com.wolfram.jlink.MathCanvas"];
		drawArea@setUsesFE[UseFrontEndForRendering];
		drawArea@setSize[400, 272];
		JavaBlock[
			frame@setLayout[JavaNew["java.awt.BorderLayout"]];
			sliderHor = JavaNew["java.awt.Scrollbar", Scrollbar`HORIZONTAL, 30, 1, 0, 90];
			sliderVer = JavaNew["java.awt.Scrollbar", Scrollbar`VERTICAL, 15, 1, 0, 90];
			okButton = JavaNew["java.awt.Button", "OK"];
			frame@add[sliderHor, ReturnAsJavaObject[BorderLayout`NORTH]];
			frame@add[sliderVer, ReturnAsJavaObject[BorderLayout`EAST]];
			frame@add[drawArea, ReturnAsJavaObject[BorderLayout`CENTER]];
		    frame@add[okButton, ReturnAsJavaObject[BorderLayout`SOUTH]];
			frame@pack[];
			listener = JavaNew["com.wolfram.jlink.MathAdjustmentListener"];
			listen = JavaNew["com.wolfram.jlink.MathAdjustmentListener"];
			listener@setHandler["adjustmentValueChanged", "sliderHorFunc"];
			sliderHor@addAdjustmentListener[listener];
			listen@setHandler["adjustmentValueChanged", "sliderVerFunc"];
			sliderVer@addAdjustmentListener[listen];
			okButton@addActionListener[JavaNew["com.wolfram.jlink.MathActionListener",
			 "buttonFunc"]];
			tok = ShareFrontEnd[];
			frame@onClose["UnshareFrontEnd[" <> ToString[tok] <> "]"]; 
			frame@setLocation[200, 200];
			JavaShow[frame]
		];
		frame
	]

sliderHorFunc[evt_, type_, scrollPos_] :=
	JavaBlock[
	    theta = (90-scrollPos)*Pi/45;
	    draw3D[];
		ReleaseObject[evt]
	]
	
sliderVerFunc[evt_, type_, scrollPos_] :=
	JavaBlock[
	    phi = scrollPos*Pi/45;
	    draw3D[];		
		ReleaseObject[evt]
	]	

draw3D[] :=
		Block[{ $DisplayFunction = Identity, obj},
				obj = Show[expr, SphericalRegion->True,
			 	 ViewPoint->{ rho Sin[phi] Cos[theta], rho Sin[phi] Sin[theta], rho  Cos[phi]}];
				drawArea@setMathCommand[ToString[obj, InputForm]];
				drawArea@repaintNow[]
			]

buttonFunc[event_, _] :=
  JavaBlock[
		NotebookApply[SelectedNotebook[],
		  ToString[ViewPoint->{ rho Sin[phi] Cos[theta], rho Sin[phi] Sin[theta], rho  Cos[phi]},InputForm]];
		 Show[expr, SphericalRegion->True,
			 	 ViewPoint->{ rho Sin[phi] Cos[theta], rho Sin[phi] Sin[theta], rho  Cos[phi]}];  
		ReleaseJavaObject[event];
		EndModal[]; 
		frm@dispose[];
	]
  

SelectorViewPoint[text_] :=
	JavaBlock[
		Block[{frm, lastScrollPos, rho, phi, theta, expr},
		    expr = text;
		    rho = 6.0; phi = Pi/3; theta = Pi/6;
		    frm = createWindow[];
			frm@setModal[];
			DoModal[];
			frm@dispose[];
		]
	]

Ilustración de una corrida.

SelectorViewPoint recibe el resultado de un comando Plot3D o ParametricPlot3D, crea una ventana JAVA con barras que permiten girar el gráfico a fin de buscar el mejor ángulo desde el cual se quiere observarlo. Al presionar el botón Ok se obtiene el valor para el ViewPoint correspondiente al último gráfico mostrado en la ventana. Si se desea que este resultado sea insertado en la línea de comando, debe moverse el punto de inserción al lugar apropiado en la línea de comando.

ParametricPlot3D[{(u + t) Sin[u] Cos[t],  (u + t) Sin[u] 
              Sin[t],  (u + t) Cos[u]},  {t, 0, 3  Pi/2},  {u, 0, 
            5  Pi/2},  PlotPoints -> 30,  Boxed -> False,  Axes -> False] // 
        SelectorViewPoint;

ViewPoint  ->  {1.0109405079950224,  -5.733328523707276,  
        1.451531373598006}