summaryrefslogtreecommitdiff
path: root/cad/src/exprs/DragBehavior_AlongCircle.py
blob: f9f508c06d288f4c959582dda1c07cb007fd69fd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# Copyright 2008 Nanorex, Inc.  See LICENSE file for details.
"""
@version: $Id$

TODO: as of 2008-02-12

This is a non-working DragBehavior_AlongCircle class , not called anywhere.
"""
from exprs.Highlightable import SavedCoordsys
from exprs.geometry_exprs import Ray
from exprs.Exprs import tuple_Expr
from exprs.attr_decl_macros import Arg, Option, Instance
from exprs.ExprsConstants import StateRef ##, ORIGIN
from exprs.__Symbols__ import Anything
from exprs.DragBehavior import DragBehavior


class DragBehavior_AlongCircle(DragBehavior):
    """
    A drag behavior which moves the original hitpoint along a line,
    storing only its 1d-position-offset along the line's direction
    [noting that the hitpoint is not necessarily equal to the moved object's origin]
    [#doc better]
    """

    highlightable = Arg(Anything)

    rotation_parameter_ref = Arg(StateRef,
                             doc = "where anything proportional to angle is stored")

    #translation_parameter_ref = Arg(StateRef,
                             #doc = "where translation is stored")
    origin = Arg(StateRef, doc = "handle base point")

    center = Arg(StateRef, doc = "center of the circle")

    axis = Arg(StateRef, doc = "circle axis")

    radiusVector = Arg(StateRef,
                       doc = "radius of circle")


    locked_parameter = Option(tuple_Expr,
                                 None,
                                 doc = "locked parameter")

    range_for_rotation =  Option(tuple_Expr,
                                 None,
                                 doc = "range limit of angle of rotation")

    range_for_translation = Option(tuple_Expr,
                                   None,
                                   doc = "range limit of translation")

    # provides transient state for saving a fixed coordsys to use throughout
    #a drag
    saved_coordsys = Instance( SavedCoordsys() )

    # helper methods (these probably belong in a superclass):
    def current_event_mousepoint(self, *args, **kws):
        return self.saved_coordsys.current_event_mousepoint(*args, **kws)

    def current_event_mouseray(self):
        p0 = self.current_event_mousepoint(depth = 0.0) # nearest depth ###k
        p1 = self.current_event_mousepoint(depth = 1.0) # farthest depth ###k
        return Ray(p0, p1 - p0)

    # specific methods
    def _C__rotation(self):
        """
        Compute self._rotation from the externally stored rotation paramater
        """
        k = self.rotation_parameter_ref.value

        ##rotation = k*self.radiusVector

        #REVISE THIS
        from geometry.VQT import norm
        return  self.origin#self.radiusVector + k*norm(self.radiusVector)

    def on_press(self):
        self.saved_coordsys.copy_from( self.highlightable)
        self.startpoint = self.current_event_mousepoint()
        #Formula needs to be revised.
        ##self.offset = self.startpoint - (ORIGIN + self._rotation)
        ##self.circularPath = self.constrain_to_circle + self.offset

    def on_drag(self):
        mouseray = self.current_event_mouseray()
        ##k = self.circularPath.closest_pt_params_to_ray(mouseray)
        k = None
        if k is not None:
            # store k, after range-limiting

            if self.range_for_rotation is not None:
                low, high = self.range_for_rotation
                if low is not None and k < low:
                    k = low
                if high is not None and k > high:
                    k = high
            self.rotation_parameter_ref.value = k
            ##e by analogy with DraggableObject, should we perhaps save this
            ##side effect until the end?
        return

    def on_release(self):
        pass