<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Visualization in OpenGL using ArcBall with zooming and panning in Discussions</title>
    <link>https://community.jmp.com/t5/Discussions/Visualization-in-OpenGL-using-ArcBall-with-zooming-and-panning/m-p/920634#M107945</link>
    <description>&lt;P&gt;I created an interactive 3D visualization of color data using the OpenGL functionality in JMP and used the ArcBall to allow the user to rotate the data, but I ran into some limitations when trying to combine this with panning and zooming.&lt;/P&gt;
&lt;P&gt;The ArcBall itself does not have panning and zooming capability and there seems to be no way to get and set the ArcBalls orientation. So if I control panning and zooming myself, I cannot integrate the Arcball seamlessly because I have to rebuild the scene from scratch disregarding the ArcBall orientation. One possible way I have been thingking of is to capture the mouse and make the Arcball functionality myself, but in the first round this was beyond the project budget.&lt;/P&gt;
&lt;P&gt;I have gone through all the examples, and none combine rotation of the Arcball with zooming and panning.&lt;/P&gt;
&lt;P&gt;Any solutions/suggestions on how to make seamless panning, zooming and ArcBall-like rotation of OpenGL scenes in JSL?&lt;/P&gt;
&lt;P&gt;Or&amp;nbsp;would it be better to use the Python integration for that?&lt;/P&gt;</description>
    <pubDate>Fri, 19 Dec 2025 10:30:58 GMT</pubDate>
    <dc:creator>thomasz</dc:creator>
    <dc:date>2025-12-19T10:30:58Z</dc:date>
    <item>
      <title>Visualization in OpenGL using ArcBall with zooming and panning</title>
      <link>https://community.jmp.com/t5/Discussions/Visualization-in-OpenGL-using-ArcBall-with-zooming-and-panning/m-p/920634#M107945</link>
      <description>&lt;P&gt;I created an interactive 3D visualization of color data using the OpenGL functionality in JMP and used the ArcBall to allow the user to rotate the data, but I ran into some limitations when trying to combine this with panning and zooming.&lt;/P&gt;
&lt;P&gt;The ArcBall itself does not have panning and zooming capability and there seems to be no way to get and set the ArcBalls orientation. So if I control panning and zooming myself, I cannot integrate the Arcball seamlessly because I have to rebuild the scene from scratch disregarding the ArcBall orientation. One possible way I have been thingking of is to capture the mouse and make the Arcball functionality myself, but in the first round this was beyond the project budget.&lt;/P&gt;
&lt;P&gt;I have gone through all the examples, and none combine rotation of the Arcball with zooming and panning.&lt;/P&gt;
&lt;P&gt;Any solutions/suggestions on how to make seamless panning, zooming and ArcBall-like rotation of OpenGL scenes in JSL?&lt;/P&gt;
&lt;P&gt;Or&amp;nbsp;would it be better to use the Python integration for that?&lt;/P&gt;</description>
      <pubDate>Fri, 19 Dec 2025 10:30:58 GMT</pubDate>
      <guid>https://community.jmp.com/t5/Discussions/Visualization-in-OpenGL-using-ArcBall-with-zooming-and-panning/m-p/920634#M107945</guid>
      <dc:creator>thomasz</dc:creator>
      <dc:date>2025-12-19T10:30:58Z</dc:date>
    </item>
    <item>
      <title>Re: Visualization in OpenGL using ArcBall with zooming and panning</title>
      <link>https://community.jmp.com/t5/Discussions/Visualization-in-OpenGL-using-ArcBall-with-zooming-and-panning/m-p/920741#M107961</link>
      <description>&lt;P&gt;This might help.&lt;/P&gt;
&lt;LI-SPOILER&gt;
&lt;PRE&gt;&lt;CODE class=" language-jsl"&gt;// cobbled together from several examples...

Cube = Scene Display List( 1 );

Cube &amp;lt;&amp;lt; Begin( QUAD_STRIP );
Cube &amp;lt;&amp;lt; Color( 1.0, 0.0, 1.0 );
Cube &amp;lt;&amp;lt; Vertex( -0.5, 0.5, 0.5 );
Cube &amp;lt;&amp;lt; Color( 1.0, 0.0, 0.0 );
Cube &amp;lt;&amp;lt; Vertex( -0.5, -0.5, 0.5 );
Cube &amp;lt;&amp;lt; Color( 1.0, 1.0, 1.0 );
Cube &amp;lt;&amp;lt; Vertex( 0.5, 0.5, 0.5 );
Cube &amp;lt;&amp;lt; Color( 1.0, 1.0, 0.0 );
Cube &amp;lt;&amp;lt; Vertex( 0.5, -0.5, 0.5 );
Cube &amp;lt;&amp;lt; Color( 0.0, 1.0, 1.0 );
Cube &amp;lt;&amp;lt; Vertex( 0.5, 0.5, -0.5 );
Cube &amp;lt;&amp;lt; Color( 0.0, 1.0, 0.0 );
Cube &amp;lt;&amp;lt; Vertex( 0.5, -0.5, -0.5 );
Cube &amp;lt;&amp;lt; Color( 0.0, 0.0, 1.0 );
Cube &amp;lt;&amp;lt; Vertex( -0.5, 0.5, -0.5 );
Cube &amp;lt;&amp;lt; Color( 0.0, 0.0, 0.0 );
Cube &amp;lt;&amp;lt; Vertex( -0.5, -0.5, -0.5 );
Cube &amp;lt;&amp;lt; Color( 1.0, 0.0, 1.0 );
Cube &amp;lt;&amp;lt; Vertex( -0.5, 0.5, 0.5 );
Cube &amp;lt;&amp;lt; Color( 1.0, 0.0, 0.0 );
Cube &amp;lt;&amp;lt; Vertex( -0.5, -0.5, 0.5 );
Cube &amp;lt;&amp;lt; End();

cube1 = Scene Display List();
cube1 &amp;lt;&amp;lt; arcball( cube, .5 ); // don't rebuild the arcballs so
cube2 = Scene Display List();
cube2 &amp;lt;&amp;lt; arcball( cube, .5 ); // they remember their positions

WindowHeight = 600;
WindowWidth = 800;

mouseOriginY = WindowHeight / 2;
mouseOriginX = WindowWidth / 2;

mode = "done";
dx = dy = .;

mouseMatrix = Identity( 4 ); // &amp;lt;&amp;lt;&amp;lt;&amp;lt; this accumulates all the angle/size/scale changes

// this function is called with m==1 on mouse down, m==2 on mouse drags, and m=3 on mouse up (k is the shift/control/alt status)
// this function returns 0 or 1, on purpose, to allow arc balls to run or this code to adjust the mouseMatrix.
Click2d = Function( {x, y, m, k},
	{xt, xs, xr, yr, zr, degrees, radians, dx, dy},
	If(
		m == 1,
			mouseOriginX = x;
			mouseOriginY = y;
					
			If( Is Shift Key(),
				mode = "translate"
			);
			//		if(Is Alt Key(), // linux/virtualbox the alt key never makes it to JMP
			//			mode = "rotate";			
			//		);
			If( Is Control Key(),
				mode = "scale"
			);
			If( Is Control Key() &amp;amp; Is Shift Key(),
				mode = "rotate"
			);
			If( !Is Control Key() &amp;amp; !Is Shift Key(),
				Return( 0 ); // allow the arc ball to get control. 0 means this handler did NOT handle the click.
			);//
		, /*else if */ m == 2,
			dx = x - mouseOriginX;
			dy = y - mouseOriginY;
			If(
				mode == "translate",
					xt = Identity( 4 );
					xt[1, 4] = dx / WindowWidth;
					xt[2, 4] = -dy / WindowWidth;
					mouseMatrix = xt * mouseMatrix;//
				, /* else if */ mode == "scale",
					xs = Identity( 4 );
					xs[1, 1] = If( dx &amp;gt;= 0,
						(dx + WindowWidth) / WindowWidth//
					,
						WindowWidth / (WindowWidth - dx)
					);
					xs[2, 2] = If( dy &amp;gt;= 0,
						WindowHeight / (dy + WindowHeight)//
					,
						(WindowHeight - dy) / WindowHeight
					);
					mouseMatrix = xs * mouseMatrix;//
				, /* else if */ mode == "rotate",
					radians = 6 * dy / WindowWidth;
					xr = Identity( 4 ); // start out with an identity matrix then plug in the values to rotate about the x axis
					xr[2, 2] = Cos( radians );
					xr[2, 3] = -Sin( radians );
					xr[3, 2] = Sin( radians );
					xr[3, 3] = Cos( radians );
					yr = Identity( 4 ); // and the y axis
					radians = 6 * dx / WindowHeight;
					yr[1, 1] = Cos( radians );
					yr[1, 3] = Sin( radians );
					yr[3, 1] = -Sin( radians );
					yr[3, 3] = Cos( radians );
					zr = Identity( 4 ); // and the z axis
					mouseMatrix = xr * mouseMatrix;
					mouseMatrix = yr * mouseMatrix;
			);
			mouseOriginX = x;
			mouseOriginY = y;
			rebuild();//
		, /*else if */ m == 3,
			mode = "done";
			0;//
		, /* else */
		Throw( "unexpected m=" || Char( m ) )
	);
	//0 // because this function does NOT return 1, JMP will not call it again until the next mouse down.  Drags will act like moves and go to the Move2d function.
	1; // because it *does* return 1, m=1,2,3 for press,move(s),release
);





Scene = Scene Box( WindowWidth, WindowHeight, Click2d );
Scene &amp;lt;&amp;lt; Show ArcBall( "Always" );

New Window( "Matrix rotations", V List Box( Text Box( "shift-drag: pan\!nctrl-drag: zoom\!nctrl-shift-drag: rotate\!nVanilla-drag: rotate cubes" ), Scene ) );

rebuild = Function( {},
	degrees = 45;
	radians = 3.14159 * degrees / 180; // sin and cos use radians
	Scene &amp;lt;&amp;lt; clear;
	Scene &amp;lt;&amp;lt; perspective( 45, 3, 7 );
	Scene &amp;lt;&amp;lt; Translate( 0.0, 0.0, -4.5 );

	// apply the global translation/rotation/scaling 
	Scene &amp;lt;&amp;lt; MultMatrix( mouseMatrix );

	Scene &amp;lt;&amp;lt; pushmatrix;
	xt = Identity( 4 ); // translate this one left by .75
	xt[1, 4] = -.75;
	Scene &amp;lt;&amp;lt; MultMatrix( xt ); 
	Scene &amp;lt;&amp;lt; callList( Cube1 );
	Scene &amp;lt;&amp;lt; popmatrix;
	
	Scene &amp;lt;&amp;lt; pushmatrix;
	Scene &amp;lt;&amp;lt; translate( .75, 0, 0 ); // translate this one right by .75
	Scene &amp;lt;&amp;lt; calllist( Cube2 );
	Scene &amp;lt;&amp;lt; popmatrix;

	Scene &amp;lt;&amp;lt; update;
);

rebuild();&lt;/CODE&gt;&lt;/PRE&gt;
&lt;/LI-SPOILER&gt;
&lt;P&gt;&lt;div class="lia-vid-container video-embed-center"&gt;&lt;div id="lia-vid-6386717988112w728h540r812" class="lia-video-brightcove-player-container"&gt;&lt;video-js data-video-id="6386717988112" data-account="6058004218001" data-player="default" data-embed="default" class="vjs-fluid" controls="" data-application-id="" style="width: 100%; height: 100%;"&gt;&lt;/video-js&gt;&lt;/div&gt;&lt;script src="https://players.brightcove.net/6058004218001/default_default/index.min.js"&gt;&lt;/script&gt;&lt;script&gt;(function() {  var wrapper = document.getElementById('lia-vid-6386717988112w728h540r812');  var videoEl = wrapper ? wrapper.querySelector('video-js') : null;  if (videoEl) {     if (window.videojs) {       window.videojs(videoEl).ready(function() {         this.on('loadedmetadata', function() {           this.el().querySelectorAll('.vjs-load-progress div[data-start]').forEach(function(bar) {             bar.setAttribute('role', 'presentation');             bar.setAttribute('aria-hidden', 'true');           });         });       });     }  }})();&lt;/script&gt;&lt;a class="video-embed-link" href="https://community.jmp.com/t5/video/gallerypage/video-id/6386717988112"&gt;(view in My Videos)&lt;/a&gt;&lt;/div&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Fri, 19 Dec 2025 20:23:32 GMT</pubDate>
      <guid>https://community.jmp.com/t5/Discussions/Visualization-in-OpenGL-using-ArcBall-with-zooming-and-panning/m-p/920741#M107961</guid>
      <dc:creator>Craige_Hales</dc:creator>
      <dc:date>2025-12-19T20:23:32Z</dc:date>
    </item>
  </channel>
</rss>

