コード例 #1
0
ファイル: geodesic.py プロジェクト: Yongcheng123/ChimeraX
def next_direction(direction, e, vertices, normal1, normal2):
    ev = edge_vector(e, vertices)
    from chimerax.geometry import cross_product, inner_product, normalize_vector
    en1, en2 = cross_product(ev, normal1), cross_product(ev, normal2)
    d = inner_product(direction, ev) * ev + inner_product(direction, en1) * en2
    d = normalize_vector(d)
    return d
コード例 #2
0
def curve_segment_end(curve, t, length, tolerance=1e-3, max_steps=100):
    '''
    Compute a point on the curve beyond curve parameter value t which is
    a distance length from the point at position t.  Can return None if
    convergence fails.  This iteratively takes linear steps based on the
    curve velocity vector to find the desired end point.
    '''
    if length == 0:
        return t
    xyz0 = curve.position(t)
    v = curve.velocity(t)
    frac = 0.5
    from chimerax.geometry import norm, inner_product
    t1 = t + frac * length / norm(v)
    for step in range(max_steps):
        xyz1 = curve.position(t1)
        d = norm(xyz1 - xyz0)
        if abs(d - length) < tolerance * length:
            return t1
        v1 = curve.velocity(t1)
        # Want |xyz1 + v1*dt - xyz0| = length
        delta = xyz1 - xyz0
        a, b, c = (inner_product(v1, v1), 2 * inner_product(v1, delta),
                   inner_product(delta, delta) - length * length)
        dt1, dt2 = quadratic_roots(a, b, c)
        if dt1 is None:
            # No point in tangent line is within target length.
            # Go to closest approach
            dt1 = dt2 = -b / 2 * a
        dt_min = dt1 if abs(dt1) < abs(dt2) else dt2
        t1 += frac * dt_min
    return None
コード例 #3
0
ファイル: dicom_format.py プロジェクト: Yongcheng123/ChimeraX
 def z_plane_spacing(self):
   dz = self._z_spacing
   if dz is None:
     files = self._file_info
     if self.multiframe:
       f = files[0]
       fpos = f._frame_positions
       if fpos is None:
         gfov = f._grid_frame_offset_vector
         if gfov is None:
           dz = None
         else:
           dz = self._spacing(gfov)
       else:
         # TODO: Need to reverse order if z decrease as frame number increases
         z_axis = self.plane_normal()
         from chimerax.geometry import inner_product
         z = [inner_product(fp, z_axis) for fp in fpos]
         dz = self._spacing(z)
       if dz is not None and dz < 0:
         self._reverse_frames = True
         dz = abs(dz)
     elif len(files) < 2:
       dz = None
     else:
       nz = self.grid_size()[2]  # For time series just look at first time point.
       z_axis = self.plane_normal()
       from chimerax.geometry import inner_product
       z = [inner_product(f._position, z_axis) for f in files[:nz]]
       dz = self._spacing(z)
     self._z_spacing = dz
     
   return dz
コード例 #4
0
def clip_segment_with_planes(xyz_1, xyz_2, planes):

    f1 = 0
    f2 = 1
    for normal, offset in planes:
        c1 = inner_product(normal, xyz_1) - offset
        c2 = inner_product(normal, xyz_2) - offset
        if c1 < 0 and c2 < 0:
            return None, None, None, None  # All of segment is clipped
        if c1 >= 0 and c2 >= 0:
            continue  # None of segment is clipped
        f = c1 / (c1 - c2)
        if c1 < 0:
            f1 = max(f1, f)
        else:
            f2 = min(f2, f)

    if f1 == 0 and f2 == 1:
        return xyz_1, xyz_2, f1, f2

    if f1 > f2:
        return None, None, None, None

    i1 = [(1 - f1) * a + f1 * b
          for a, b in zip(xyz_1, xyz_2)]  # Intercept point
    i2 = [(1 - f2) * a + f2 * b
          for a, b in zip(xyz_1, xyz_2)]  # Intercept point
    return i1, i2, f1, f2
コード例 #5
0
 def _closest_point(self, event):
     '''Project start point to view line through mouse position.'''
     xyz1, xyz2 = self._view_line(event)
     p = self._start_point
     dx = xyz2 - xyz1
     from chimerax.geometry import inner_product
     f = inner_product(p - xyz1, dx) / inner_product(dx, dx)
     cp = xyz1 + f * dx
     return cp
コード例 #6
0
ファイル: tugatoms.py プロジェクト: Yongcheng123/ChimeraX
 def pull_direction(self, atom):
     v = atom.structure.session.main_view
     x0, x1 = v.clip_plane_points(self.x, self.y)
     axyz = atom.scene_coord
     # Project atom onto view ray to get displacement.
     dir = x1 - x0
     da = axyz - x0
     from chimerax.geometry import inner_product
     offset = da - (inner_product(da, dir) / inner_product(dir, dir)) * dir
     return axyz, -offset
コード例 #7
0
ファイル: tugging.py プロジェクト: tristanic/isolde
 def _offset_vector(self, x, y, starting_coord):
     v = self.session.main_view
     x0, x1 = v.clip_plane_points(x, y)
     axyz = starting_coord
     # Project atom onto view ray to get displacement.
     dir = x1 - x0
     da = axyz - x0
     from chimerax.geometry import inner_product
     offset = self.structure.scene_position.inverse(
         is_orthonormal=True).transform_vectors(
             da - (inner_product(da, dir) / inner_product(dir, dir)) * dir)
     return -offset
コード例 #8
0
 def _far_clip_point(self, pos):
     view = self.session.main_view
     cam = view.camera
     view_num = 0
     cam_pos = cam.get_position(view_num).origin()
     cam_dir = cam.view_direction(view_num)
     pick_dir = pos - cam_pos
     near, far = view.near_far_distances(cam, view_num)
     from chimerax.geometry import inner_product
     denom = inner_product(pick_dir, cam_dir)
     d = (far -
          inner_product(cam_pos, cam_dir)) / denom if denom != 0 else 1000
     return cam_pos + d * pick_dir
コード例 #9
0
ファイル: geodesic.py プロジェクト: Yongcheng123/ChimeraX
def next_edge(p, direction, edges, vertices):
    from chimerax.geometry import cross_product, inner_product
    for e in edges:
        ev1, ev2 = vertices[e[0]] - p, vertices[e[1]] - p
        n = cross_product(ev1, ev2)
        tn = cross_product(direction, n)
        i1, i2 = inner_product(tn, ev1), inner_product(tn, ev2)
        if (i1 < 0 and i2 > 0) or (i1 > 0 and i2 < 0):
            # Edge is split by geodesic direction
            f = i1 / (i1 - i2)
            p2 = (1 - f) * vertices[e[0]] + f * vertices[e[1]]
            return e, f
    return None, None
コード例 #10
0
 def near_far_distances(self, camera, view_num, include_clipping=True):
     '''Near and far scene bounds as distances from camera.'''
     cp = camera.get_position(view_num).origin()
     vd = camera.view_direction(view_num)
     near, far = self._near_far_bounds(cp, vd)
     if include_clipping:
         p = self.clip_planes
         np, fp = p.find_plane('near'), p.find_plane('far')
         from chimerax.geometry import inner_product
         if np:
             near = max(near, inner_product(vd, (np.plane_point - cp)))
         if fp:
             far = min(far, inner_product(vd, (fp.plane_point - cp)))
     cnear, cfar = self._clamp_near_far(near, far)
     return cnear, cfar
コード例 #11
0
def _transform_schematic(session, transform, center, from_rgba, to_rgba,
                         length, width, thickness):

    axis, rot_center, angle_deg, shift = transform.axis_center_angle_shift()

    # Align rot_center at same position along axis as center.
    from chimerax.geometry import inner_product
    rot_center += inner_product(center - rot_center, axis) * axis
    width_axis = center - rot_center
    varray, narray, tarray = _axis_square(axis, rot_center, width_axis, length,
                                          width, thickness)

    from chimerax.core.models import Model, Surface

    s1 = Surface('slab 1', session)
    s1.set_geometry(varray, narray, tarray)
    s1.color = from_rgba

    s2 = Surface('slab 2', session)
    from chimerax.geometry import rotation, translation
    rot2 = translation(shift * axis) * rotation(
        axis, angle_deg, center=rot_center)
    varray2 = rot2 * varray
    narray2 = rot2.transform_vectors(narray)
    s2.set_geometry(varray2, narray2, tarray)
    s2.color = to_rgba

    m = Model('transform schematic', session)
    m.add([s1, s2])

    return m
コード例 #12
0
def optimize_helix_paramters(v, xyz, w, axis, rise, angle, center):

    m = v.full_matrix()
    xyz_to_ijk_transform = v.data.xyz_to_ijk_transform
    max_steps = 2000
    ijk_step_size_min, ijk_step_size_max = 0.01, 0.5
    optimize_translation = optimize_rotation = True
    metric = 'correlation'

    from chimerax.geometry import helical_symmetry_matrix
    htf = helical_symmetry_matrix(rise, angle, axis, center)
    tf = xyz_to_ijk_transform * htf

    from chimerax.map_fit.fitmap import locate_maximum
    move_tf, stats = locate_maximum(xyz, w, m, tf, max_steps,
                                    ijk_step_size_min, ijk_step_size_max,
                                    optimize_translation, optimize_rotation,
                                    metric)

    ohtf = htf * move_tf
    oaxis, ocenter, oangle, orise = ohtf.axis_center_angle_shift()
    from chimerax.geometry import inner_product
    if inner_product(axis, oaxis) < 0:
        orise = -orise
        oangle = -oangle
    corr = stats['correlation']

    return orise, oangle, corr
コード例 #13
0
    def scene_position_6d(self, hand_pose, view):
        from chimerax.geometry import translation, cross_product
        from chimerax.geometry import orthonormal_frame, inner_product

        # Adjust origin
        cpos = translation(-self._center) * hand_pose

        # Scale millimeters to scene units
        scene_center = view.center_of_rotation
        cam = view.camera
        factor = cam.view_width(scene_center) / self._width
        cpos = cpos.scale_translation(factor)  # millimeters to scene units

        # Rotate to screen orientation
        yaxis = self._facing
        zaxis = cross_product(yaxis, self._cord)
        cpos = orthonormal_frame(zaxis, ydir=yaxis) * cpos

        # Adjust depth origin to center of rotation.
        cam_pos = cam.position
        depth = inner_product(scene_center - cam_pos.origin(),
                              -cam_pos.z_axis())
        cpos = translation(
            (0, 0, -depth)) * cpos  # Center in front of camera (-z axis).

        # Convert camera coordinates to scene coordinates
        scene_pos = cam_pos * cpos  # Map from camera to scene coordinates

        return scene_pos
コード例 #14
0
ファイル: tiltedslab.py プロジェクト: Yongcheng123/ChimeraX
    def mouse_drag(self, event):
        v = self._map
        if v is None or self._xy_last is None:
            self.mouse_down(event)
            return

        xl, yl = self._xy_last
        x, y = event.position()
        dx, dy = (x - xl, yl - y)
        if dx == 0 and dy == 0:
            return

        camera = self.session.main_view.camera
        if event.shift_down():
            # Translate slab
            ro = v.rendering_options
            spacing = ro.tilted_slab_spacing
            slab_normal = v.scene_position.transform_vector(
                ro.tilted_slab_axis)
            move_dir = camera.position.transform_vector((dx, dy, 0))
            from chimerax.geometry import inner_product, norm
            sign = 1 if inner_product(move_dir, slab_normal) > 0 else -1
            dist = sign * norm(move_dir) * spacing
            self._move_slab(dist)
        else:
            # Rotate slab
            from math import sqrt
            dn = sqrt(dx * dx + dy * dy)
            rangle = dn
            raxis = camera.position.transform_vector((-dy / dn, dx / dn, 0))
            self._rotate_slab(raxis, rangle)
        self._xy_last = (x, y)
コード例 #15
0
def compute_instances_cap(drawing, triangles, plane, offset):
    d = drawing
    doffset = offset + getattr(d, 'clip_offset', 0)
    point = plane.plane_point
    normal = plane.normal

    b = d.geometry_bounds()
    if b is None:
        return None, None, None

    dpos = d.get_scene_positions(displayed_only=True)
    ipos = box_positions_intersecting_plane(dpos, b, point, normal)
    if len(ipos) == 0:
        return None, None, None
    geom = []
    for pos in ipos:
        pinv = pos.inverse()
        pnormal = pinv.transform_vector(normal)
        from chimerax.geometry import inner_product
        poffset = inner_product(pnormal, pinv * point) + doffset
        from . import compute_cap
        ivarray, itarray = compute_cap(-pnormal, -poffset, d.vertices,
                                       triangles)
        pos.transform_points(ivarray, in_place=True)
        geom.append((ivarray, itarray))
    varray, tarray = concatenate_geometry(geom)
    return varray, tarray, normal
コード例 #16
0
ファイル: interpolate.py プロジェクト: Yongcheng123/ChimeraX
def interpolate_corkscrew(xf, c0, c1, minimum_rotation = 0.1):
        '''
        Rotate and move along a circular arc perpendicular to the rotation axis and
        translate parallel the rotation axis.  This makes the initial geometric center c0
        traverse a helical path to the final center c1.  The circular arc spans an angle
        equal to the rotation angle so it is nearly a straight segment for small angles,
        and for the largest possible rotation angle of 180 degrees it is a half circle
        centered half-way between c0 and c1 in the plane perpendicular to the rotation axis.
        Rotations less than the minimum (degrees) are treated as no rotation.
        '''
        from chimerax.geometry import normalize_vector
        dc = c1 - c0
        axis, angle = xf.rotation_axis_and_angle()      # a is in degrees.
        if abs(angle) < minimum_rotation:
                # Use linear instead of corkscrew interpolation to
                # avoid numerical precision problems at small rotation angles.
                # ChimeraX bug #2928.
                center = c0
                shift = dc
        else:
                from chimerax.geometry import inner_product, cross_product, norm
                tra = inner_product(dc, axis)           # Magnitude of translation along rotation axis.
                shift = tra*axis
                vt = dc - tra * axis                    # Translation perpendicular to rotation axis.
                v0 = cross_product(axis, vt)
                if norm(v0) == 0 or angle == 0:
                        center = c0
                else:
                        import math
                        l = 0.5*norm(vt) / math.tan(math.radians(angle / 2))
                        center = c0 + 0.5*vt + l*normalize_vector(v0)

        return axis, angle, center, shift
コード例 #17
0
ファイル: camera.py プロジェクト: Yongcheng123/ChimeraX
def perspective_view_all(bounds,
                         position,
                         field_of_view,
                         window_size=None,
                         pad=0):
    '''
    Return the camera position that shows the specified bounds.
    Camera has perspective projection.
    '''
    from math import radians, sin, cos
    fov2 = radians(field_of_view) / 2
    s, c = sin(fov2), cos(fov2)
    face_normals = [
        position.transform_vector(v) for v in ((c / s, 0, 1), (-c / s, 0, 1))
    ]  # frustum side normals
    if window_size is not None:
        aspect = window_size[1] / window_size[0]
        from math import tan, atan
        fov2y = atan(aspect * tan(fov2))
        sy, cy = sin(fov2y), cos(fov2y)
        face_normals.extend([
            position.transform_vector(v)
            for v in ((0, cy / sy, 1), (0, -cy / sy, 1))
        ])  # frustum top/bottom normals
    center = bounds.center()
    bc = bounds.box_corners() - center
    from chimerax.geometry import inner_product, Place
    d = max(inner_product(n, c) for c in bc for n in face_normals)
    d *= 1 / max(0.01, 1 - pad)
    view_direction = -position.z_axis()
    camera_center = center - d * view_direction
    va_position = Place(axes=position.axes(), origin=camera_center)
    return va_position
コード例 #18
0
    def clip_move(self, delta_xy, front_shift, back_shift, delta=None):
        pf, pb = self._planes(front_shift, back_shift)
        if pf is None and pb is None:
            return

        from chimerax.graphics import SceneClipPlane, CameraClipPlane
        p = pf or pb
        if delta is not None:
            d = delta
        elif isinstance(p, SceneClipPlane):
            # Move scene clip plane
            d = self._tilt_shift(delta_xy, self.view.camera, p.normal)
        elif isinstance(p, CameraClipPlane):
            # near/far clip
            d = delta_xy[1] * self.pixel_size()

        # Check if slab thickness becomes less than zero.
        dt = -d * (front_shift + back_shift)
        if pf and pb and dt < 0:
            from chimerax.geometry import inner_product
            sep = inner_product(pb.plane_point - pf.plane_point, pf.normal)
            if sep + dt <= 0:
                # Would make slab thickness less than zero.
                return

        if pf:
            pf.plane_point = pf.plane_point + front_shift * d * pf.normal
        if pb:
            pb.plane_point = pb.plane_point + back_shift * d * pb.normal
コード例 #19
0
def line_position(xyz, line):
    xyz1, xyz2 = line
    dxyz = xyz - xyz1
    xyz12 = xyz2 - xyz1
    from chimerax.geometry import norm, inner_product
    d2 = norm(xyz12)
    f = inner_product(dxyz, xyz12) / d2
    return f
コード例 #20
0
def point_in_view(point, view):
    w, h = view.window_size
    cam = view.camera
    # Compute planes bounding view
    planes = cam.rectangle_bounding_planes((0, 0), (w, h), (w, h))
    from chimerax.geometry import inner_product
    for p in planes:
        if inner_product(point, p[:3]) + p[3] < 0:
            return False

    # Check near/far planes
    near, far = view.near_far_distances(cam, view_num=0)
    dist = inner_product(point - cam.position.origin(), cam.view_direction())
    if dist < near or dist > far:
        return False

    return True
コード例 #21
0
def circle_in_circles(i, circles):
    from chimerax.geometry import inner_product
    p, a = circles[i].center, circles[i].angle
    for j, c in enumerate(circles):
        if c.angle >= a and inner_product(
                p, c.center) >= cos(c.angle - a) and j != i:
            return True
    return False
コード例 #22
0
 def _near_far_bounds(self, camera_pos, view_dir):
     b = self.drawing_bounds(allow_drawing_changes=False)
     if b is None:
         return self._min_near_fraction, 1  # Nothing shown
     from chimerax.geometry import inner_product
     d = inner_product(b.center() - camera_pos,
                       view_dir)  # camera to center of drawings
     r = (1 + self._near_far_pad) * b.radius()
     return (d - r, d + r)
コード例 #23
0
 def _shift_near_far_clip_planes(self, shift):
     p = self.clip_planes
     np, fp = p.find_plane('near'), p.find_plane('far')
     if np or fp:
         vd = self.camera.view_direction()
         from chimerax.geometry import inner_product
         plane_shift = inner_product(shift, vd) * vd
         if np:
             np.plane_point += plane_shift
         if fp:
             fp.plane_point += plane_shift
コード例 #24
0
def circle_intercepts(c0, c1):

    from chimerax.geometry import inner_product, cross_product
    ca01 = inner_product(c0.center, c1.center)
    x01 = cross_product(c0.center, c1.center)
    s2 = inner_product(x01, x01)
    if s2 == 0:
        return None, None

    ca0 = c0.cos_angle
    ca1 = c1.cos_angle
    a = (ca0 - ca01 * ca1) / s2
    b = (ca1 - ca01 * ca0) / s2
    d2 = (s2 - ca0 * ca0 - ca1 * ca1 + 2 * ca01 * ca0 * ca1)
    if d2 < 0:
        return None, None
    d = sqrt(d2) / s2

    return (a * c0.center + b * c1.center - d * x01,
            a * c0.center + b * c1.center + d * x01)
コード例 #25
0
ファイル: camera.py プロジェクト: Yongcheng123/ChimeraX
 def set_focus_depth(self, point_on_screen, window_width):
     from chimerax.geometry import inner_product
     z = inner_product(self.view_direction(),
                       point_on_screen - self.position.origin())
     if z <= 0:
         return
     from math import tan, radians
     screen_width = 2 * z * tan(0.5 * radians(self.field_of_view))
     es = screen_width * self.eye_separation_pixels / window_width
     self.eye_separation_scene = es
     self.redraw_needed = True
コード例 #26
0
ファイル: mouse_rot.py プロジェクト: Yongcheng123/ChimeraX
 def vr_motion(self, event):
     # Virtual reality hand controller motion.
     br = self._bond_rot
     if br:
         axis, angle = event.motion.rotation_axis_and_angle()
         from chimerax.geometry import inner_product
         if inner_product(axis, br.axis) < 0:
             angle = -angle
         angle_change = self._speed_factor * angle
         if abs(angle_change) < self._minimum_angle_step:
             return "accumulate drag"
         br.angle += angle_change
コード例 #27
0
 def _center_point_matching_depth(self, point):
     cam_pos = self.camera.position.origin()
     vd = self.camera.view_direction()
     hyp = point - cam_pos
     from chimerax.geometry import inner_product, norm
     distance = inner_product(hyp, vd)
     cr = cam_pos + distance * vd
     old_cofr = self._center_of_rotation
     if norm(cr - old_cofr) < 1e-6 * distance:
         # Avoid jitter if camera has not moved
         cr = old_cofr
     return cr
コード例 #28
0
ファイル: lookingglass.py プロジェクト: Yongcheng123/ChimeraX
 def _update_focus_depth(self):
     v = self._session.main_view
     b = v.drawing_bounds()
     if b is None:
         return
     view_dir = -self.position.z_axis()
     delta = b.center() - self.position.origin()
     from chimerax.geometry import inner_product
     d = inner_product(delta, view_dir)
     d -= self._depth_offset
     if d != self._focus_depth:
         self._focus_depth = d
         self._redraw_needed()
コード例 #29
0
ファイル: zoom.py プロジェクト: Yongcheng123/ChimeraX
def zoom_camera(c, point, factor):
    if hasattr(c, 'field_width'):
        # Orthographic camera
        c.field_width /= factor
    else:
        # Perspective camera
        v = c.view_direction()
        p = c.position
        from chimerax.geometry import inner_product, translation
        delta_z = inner_product(p.origin() - point, v)
        zmove = (delta_z * (1 - factor) / factor) * v
        c.position = translation(zmove) * p
    c.redraw_needed = True
コード例 #30
0
ファイル: tiltedslab.py プロジェクト: Yongcheng123/ChimeraX
    def vr_motion(self, event):
        v = self._map
        if v is None:
            return

        trans = event.tip_motion
        dxyz = v.scene_position.inverse().transform_vector(trans)
        ro = v.rendering_options
        from chimerax.geometry import inner_product
        dist = inner_product(ro.tilted_slab_axis, dxyz)
        self._move_slab(dist)
        center = event.tip_position
        axis, angle = event.motion.rotation_axis_and_angle()
        self._rotate_slab(axis, angle, center)