class_docstr: Virtual Trackball Control.
  
  >>> ball = Arcball()
  >>> ball = Arcball(initial=numpy.identity(4))
  >>> ball.place([320, 320], 320)
  >>> ball.down([500, 250])
  >>> ball.drag([475, 275])
  >>> R = ball.matrix()
  >>> numpy.allclose(numpy.sum(R), 3.90583455)
  True
  >>> ball = Arcball(initial=[1, 0, 0, 0])
  >>> ball.place([320, 320], 320)
  >>> ball.setaxes([1, 1, 0], [-1, 1, 0])
  >>> ball.constrain = True
  >>> ball.down([400, 200])
  >>> ball.drag([200, 400])
  >>> R = ball.matrix()
  >>> numpy.allclose(numpy.sum(R), 0.2055924)
  True
  >>> ball.next()
docstr: Initialize virtual trackball control.
  
  initial : quaternion or rotation matrix
docstr_tok: ["Initialize","virtual","trackball","control",".","initial",":","quaternion","or","rotation","matrix"]
code: def __init__(self, initial=None):
      """Initialize virtual trackball control.
  
      initial : quaternion or rotation matrix
  
      """
      self._axis = None
      self._axes = None
      self._radius = 1.0
      self._center = [0.0, 0.0]
      self._vdown = numpy.array([0.0, 0.0, 1.0])
      self._constrain = False
      if initial is None:
          self._qdown = numpy.array([1.0, 0.0, 0.0, 0.0])
      else:
          initial = numpy.array(initial, dtype=numpy.float64)
          if initial.shape == (4, 4):
              self._qdown = quaternion_from_matrix(initial)
          elif initial.shape == (4,):
              initial /= vector_norm(initial)
              self._qdown = initial
          else:
              raise ValueError("initial not a quaternion or matrix")
      self._qnow = self._qpre = self._qdown
  
imports: import math
  import numpy
label_desc: Use image node_id 1 to create a new Arcball object  with example: obj = Arcball(initial)