~lib2geom-hackers/lib2geom/trunk

« back to all changes in this revision

Viewing changes to elip.py

  • Committer: njh
  • Date: 2006-05-22 11:50:24 UTC
  • Revision ID: svn-v4:4601daaa-0314-0410-9a8b-c964a3c23b6b:trunk/lib2geom:1
initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/python
 
2
 
 
3
import gtk,gtk.gdk,math,pango  #Numeric,
 
4
 
 
5
templayout = None
 
6
 
 
7
def draw_spot(w, h):
 
8
    x,y = h.x, h.y
 
9
    g = gtk.gdk.GC(w)
 
10
    w.draw_line(g, int(x), int(y), int(x), int(y))
 
11
 
 
12
def draw_handle(w, h, name = ""):
 
13
    x,y = h.x, h.y
 
14
    g = gtk.gdk.GC(w)
 
15
    w.draw_line(g, int(x-3), int(y), int(x+3), int(y))
 
16
    w.draw_line(g, int(x), int(y-3), int(x), int(y+3))
 
17
    templayout.set_text(name)
 
18
    w.draw_layout(g, x, y, templayout)
 
19
 
 
20
def draw_ray(w, h, d):
 
21
    x,y = h.x, h.y
 
22
    g = gtk.gdk.GC(w)
 
23
    w.draw_line(g, int(h.x), int(h.y), int(3*d.x-2*h.x), int(3*d.y-2*h.y))
 
24
 
 
25
def intersect(n0, d0, n1, d1):
 
26
    denominator = n0.x*n1.y - n0.y*n1.x
 
27
    X = n1.y * d0 - n0.y * d1
 
28
    if denominator == 0:
 
29
        return None;
 
30
 
 
31
    Y = n0.x * d1 - n1.x * d0
 
32
 
 
33
    return handle(X / denominator, Y / denominator)
 
34
 
 
35
def seg(a0, a1, b0, b1):
 
36
    n0 = handle(a1.y - a0.y, -a1.x + a0.x)
 
37
    d0 = n0.x*a0.x + n0.y *a0.y
 
38
    n1 = handle(b1.y - b0.y, -b1.x + b0.x)
 
39
    d1 = n1.x*b0.x + n1.y *b0.y
 
40
 
 
41
    return intersect(n0, d0, n1, d1)
 
42
 
 
43
def draw_elip(w, h):
 
44
    g = gtk.gdk.GC(w)
 
45
    w.draw_line(g, h[0].x, h[0].y, h[1].x, h[1].y)
 
46
    w.draw_line(g, h[3].x, h[3].y, h[4].x, h[4].y)
 
47
    w.draw_line(g, h[3].x, h[3].y, h[2].x, h[2].y)
 
48
    w.draw_line(g, h[2].x, h[2].y, h[1].x, h[1].y)
 
49
 
 
50
    c = seg(h[0], h[1], h[3], h[4])
 
51
    draw_handle(w, c)
 
52
    
 
53
    if 0:
 
54
        for i in range(6):
 
55
            w.draw_line(g, h[i].x, h[i].y, h[(i+1)%6].x, h[(i+1)%6].y)
 
56
        
 
57
    
 
58
    cx,cy = c.x, c.y
 
59
 
 
60
    ox, oy = None, None
 
61
    for i in range(0, 101):
 
62
        t = i/100.0
 
63
        
 
64
        
 
65
        nx = (1-t)*h[0].x + t*h[3].x
 
66
        ny = (1-t)*h[0].y + t*h[3].y
 
67
        #w.draw_line(g, 2*cx-nx, 2*cy-ny, nx, ny)
 
68
        c1 = seg(handle(2*cx-nx, 2*cy-ny), handle(nx, ny), h[0], h[2])
 
69
        #draw_handle(w, c1)
 
70
        c2 = seg(handle(2*cx-nx, 2*cy-ny), handle(nx, ny), h[4], h[2])
 
71
        #draw_handle(w, c2)
 
72
        #draw_ray(w, h[3], c1)
 
73
        #draw_ray(w, h[1], c2)
 
74
        six = seg(c1, h[3], c2, h[1])
 
75
        #draw_spot(w, six)
 
76
        if ox:
 
77
            w.draw_line(g, ox, oy, six.x, six.y)
 
78
        ox, oy = six.x, six.y
 
79
    return
 
80
    
 
81
    r = math.hypot(h[0].x - cx, h[0].y - cy)
 
82
    s = math.atan2(h[0].y - h[3].y, h[0].x - h[3].x)
 
83
    e = math.atan2(h[1].y - h[4].y, h[1].x - h[4].x)
 
84
    for i in range(0, 101):
 
85
        t = (e-s)*i/100.0 + s
 
86
        nx, ny = r*math.cos(t)+cx, r*math.sin(t)+cy
 
87
        sx, sy = r*math.cos(t+math.pi)+cx, r*math.sin(t+math.pi)+cy
 
88
        w.draw_line(g, sx, sy, nx, ny)
 
89
    
 
90
 
 
91
class handle:
 
92
    def __init__(self, x, y):
 
93
        self.x = x
 
94
        self.y = y
 
95
    def __repr__(self):
 
96
        return "handle(%f, %f)" % (self.x, self.y)
 
97
 
 
98
handles = [handle(145.000000, 50.000000), handle(43.000000, 69.000000), handle(26.000000, 135.000000), handle(48.000000, 189.000000), handle(248.000000, 188.000000)]
 
99
 
 
100
selected_handle = None
 
101
 
 
102
def display(da, ev):
 
103
    g = gtk.gdk.GC(da.window)
 
104
    i = 0
 
105
 
 
106
    
 
107
    
 
108
    for h in handles:
 
109
        draw_handle(da.window, h, str(i))
 
110
        i += 1
 
111
    draw_elip(da.window, handles)
 
112
 
 
113
def mouse_event(w, e):
 
114
    global selected_handle
 
115
    if e.button == 1:
 
116
        for h in handles:
 
117
            if math.hypot(e.x-h.x, e.y - h.y) < 5:
 
118
                selected_handle = (h, (e.x-h.x, e.y-h.y))
 
119
 
 
120
def mouse_release_event(w, e):
 
121
    global selected_handle
 
122
    selected_handle = None
 
123
 
 
124
def mouse_motion_event(w, e):
 
125
    global selected_handle
 
126
    if selected_handle:
 
127
        h, (ox, oy) = selected_handle
 
128
        if(e.state & gtk.gdk.BUTTON1_MASK):
 
129
            h.x = e.x - ox
 
130
            h.y = e.y - oy
 
131
            w.queue_draw()
 
132
 
 
133
 
 
134
win = gtk.Window()
 
135
win.set_default_size(400,400)
 
136
vb = gtk.VBox(False)
 
137
 
 
138
da = gtk.DrawingArea()
 
139
templayout = da.create_pango_layout("")
 
140
da.connect("expose_event", display)
 
141
da.add_events(gtk.gdk.BUTTON_PRESS_MASK | gtk.gdk.BUTTON_RELEASE_MASK | gtk.gdk.KEY_PRESS_MASK | gtk.gdk.POINTER_MOTION_MASK)
 
142
da.connect("button-press-event", mouse_event)
 
143
da.connect("button-release-event", mouse_release_event)
 
144
da.connect("motion-notify-event", mouse_motion_event)
 
145
#da.connect("key_press_event", key_event)
 
146
win.add(vb)
 
147
vb.pack_start(da)
 
148
win.connect("destroy", gtk.main_quit)
 
149
 
 
150
 
 
151
win.show_all()
 
152
 
 
153
gtk.main()
 
154
 
 
155
print handles