Opened 3 years ago

Last modified 10 months ago

## #926 new enhancement

# draw orientation diagrams with interactive svg

Reported by: | pkienzle | Owned by: | |
---|---|---|---|

Priority: | major | Milestone: | sasmodels Next Release +1 |

Component: | SasView | Keywords: | |

Cc: | Work Package: | SasView Bug Fixing |

### Description

Orientation diagrams for the different shapes will be easier to understand if the user can adjust the orientation parameters to see how the shape moves with respect to the beam and the detector.

This can be done with an svg diagram, which allows interactors with javascript callbacks. E.g.,

For generating the pdf, these would have to be converted to png files for the default orientation prior to building the pdf, probably by using convert from ImageMagick?:

http://tex.stackexchange.com/questions/2099/how-to-include-svg-diagrams-in-latex

Maybe need a sphinx plugin to automate this.

### Change History (2)

### comment:1 Changed 10 months ago by pkienzle

### comment:2 Changed 10 months ago by pkienzle

The new jitter view for jupyter notebooks redraws the entire plot on each update. Instead, should keep handles to the individual items on the scene and update the data traits with changes in parameters. This will bring interactive use on par with the matplotlib 3d option while having much better rendering of the 3D objects.

For example:

import numpy as np from numpy import pi, sin, cos, degrees, radians, sqrt, arccos import ipyvolume as ipv import ipywidgets as widgets def transform_xyz(theta, phi, x, y, z): x, y, z = [np.asarray(v) for v in (x, y, z)] shape = x.shape points = np.matrix([x.flatten(), y.flatten(), z.flatten()]) Ry_theta = [[+cos(theta), 0, +sin(theta)], [0, 1, 0], [-sin(theta), 0, +cos(theta)]] Rz_phi = [[+cos(phi), -sin(phi), 0], [+sin(phi), +cos(phi), 0], [0, 0, 1]] points = np.matrix(Rz_phi)*np.matrix(Ry_theta)*points x, y, z = [np.array(v).reshape(shape) for v in points] return x, y, z def torus(R=100, r=10, Rsteps=100, rsteps=100): u = np.linspace(0, 2*pi, rsteps) # tube v = np.linspace(0, 2*pi, Rsteps) # ring U, V = np.meshgrid(u, v) x = (R + r*cos(U))*cos(V) y = (R + r*cos(U))*sin(V) z = r*sin(U) return x, y, z class Scene: def __init__(self, view=(0, 0, 0), hkl=(1,1,1)): self.view = view self.figure = ipv.figure() R = 100. r = R/30. ipv.xlim(-R, R) ipv.ylim(-R, R) ipv.zlim(-R, R) ipv.style.box_off() self.torus_xyz = torus(R=R, r=R/10) self.torus = ipv.plot_surface(*self.torus_xyz) ipv.show() widgets.interact(self.update, theta=(-90.,90.), phi=(-180., 180.)) def update(self, theta, phi): x, y, z = transform_xyz(radians(theta), radians(phi), *self.torus_xyz) self.torus.x = x.flatten() self.torus.y = y.flatten() self.torus.z = z.flatten() scene = Scene()

**Note:**See TracTickets for help on using tickets.

The jitter viewer has been updated to use ipyvolume in a jupyter notebook (sasmodels PR #96). This is a thin wrapper around threejs. It should be easy enough to translate the jitter orientation code from python to javascript, and use it to update the existing scene, making it a standalone solution for the documentation.