1 #include "broken_edge.h" |
|
2 #include <cmath> |
|
3 |
|
4 BrokenEdge::BrokenEdge(Gnome::Canvas::Group & g, Gnome::Canvas::Points p, GraphDisplayerCanvas & gc) : Line(g), gdc(gc), isbutton(false) |
|
5 { |
|
6 my_points=new Gnome::Art::Point[3]; |
|
7 |
|
8 arrow=new Gnome::Canvas::Polygon(g); |
|
9 *arrow << Gnome::Canvas::Properties::fill_color("red"); |
|
10 arrow->signal_event().connect(sigc::mem_fun(*this, &BrokenEdge::edgeFormerEventHandler)); |
|
11 arrow->lower_to_bottom(); |
|
12 setPoints(p); |
|
13 } |
|
14 |
|
15 BrokenEdge::~BrokenEdge() |
|
16 { |
|
17 if(arrow)delete(arrow); |
|
18 } |
|
19 |
|
20 void BrokenEdge::setPoints(Gnome::Canvas::Points p, bool move) |
|
21 { |
|
22 bool set_arrow=false; |
|
23 //red arrow losts its position-right button |
|
24 if(!move) |
|
25 { |
|
26 if(p.size()==2) |
|
27 { |
|
28 set_arrow=true; |
|
29 Gnome::Canvas::Points points_with_center; |
|
30 points_with_center.push_back(my_points[0]=p[0]); |
|
31 points_with_center.push_back(my_points[1]=Gnome::Art::Point( (p[0].get_x()+p[1].get_x())/2+0 , (p[0].get_y()+p[1].get_y())/2 )+0 ); |
|
32 points_with_center.push_back(my_points[2]=p[1]); |
|
33 property_points().set_value(points_with_center); |
|
34 } |
|
35 if(p.size()==3) |
|
36 { |
|
37 set_arrow=true; |
|
38 property_points().set_value(p); |
|
39 for(int i=0;i<3;i++) |
|
40 { |
|
41 my_points[i]=p[i]; |
|
42 } |
|
43 } |
|
44 } |
|
45 else |
|
46 { |
|
47 //arrow keeps its position-left button |
|
48 |
|
49 // if(p.size()==2) |
|
50 // { |
|
51 // Gnome::Canvas::Points points; |
|
52 // my_points[0]=p[0]; |
|
53 // my_points[2]=p[1]; |
|
54 // for(int i=0;i<3;i++) |
|
55 // { |
|
56 // points.push_back(my_points[i]); |
|
57 // } |
|
58 // property_points().set_value(points); |
|
59 // } |
|
60 set_arrow=true; |
|
61 |
|
62 ////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
63 /////////// keeps shape-with scalar multiplication - version 2. |
|
64 ////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
65 |
|
66 if(p.size()==2) |
|
67 { |
|
68 //old vector from one to the other node - a |
|
69 xy<double> a_v(my_points[2].get_x()-my_points[0].get_x(),my_points[2].get_y()-my_points[0].get_y()); |
|
70 //new vector from one to the other node - b |
|
71 xy<double> b_v(p[1].get_x()-p[0].get_x(),p[1].get_y()-p[0].get_y()); |
|
72 |
|
73 double absa=sqrt(a_v.normSquare()); |
|
74 double absb=sqrt(b_v.normSquare()); |
|
75 |
|
76 //old vector from one node to the breakpoint - c |
|
77 xy<double> c_v(my_points[1].get_x()-my_points[0].get_x(),my_points[1].get_y()-my_points[0].get_y()); |
|
78 |
|
79 //unit vector with the same direction to a_v |
|
80 xy<double> a_v_u(a_v.x/absa,a_v.y/absa); |
|
81 |
|
82 //normal vector of unit vector with the same direction to a_v |
|
83 xy<double> a_v_u_n(((-1)*a_v_u.y),a_v_u.x); |
|
84 |
|
85 //unit vector with the same direction to b_v |
|
86 xy<double> b_v_u(b_v.x/absb,b_v.y/absb); |
|
87 |
|
88 //normal vector of unit vector with the same direction to b_v |
|
89 xy<double> b_v_u_n(((-1)*b_v_u.y),b_v_u.x); |
|
90 |
|
91 //vector c in a_v_u and a_v_u_n co-ordinate system |
|
92 xy<double> c_a(c_v*a_v_u,c_v*a_v_u_n); |
|
93 |
|
94 //new vector from one node to the breakpoint - d - we have to calculate this one |
|
95 xy<double> d_v=absb/absa*(c_a.x*b_v_u+c_a.y*b_v_u_n); |
|
96 |
|
97 my_points[1]=Gnome::Art::Point(d_v.x+p[0].get_x(),d_v.y+p[0].get_y()); |
|
98 |
|
99 my_points[0]=p[0]; |
|
100 my_points[2]=p[1]; |
|
101 |
|
102 Gnome::Canvas::Points points; |
|
103 for(int i=0;i<3;i++) |
|
104 { |
|
105 points.push_back(my_points[i]); |
|
106 } |
|
107 property_points().set_value(points); |
|
108 } |
|
109 } |
|
110 if(set_arrow) |
|
111 { |
|
112 //calculating coordinates of the direction indicator arrow |
|
113 |
|
114 xy<gdouble> target( my_points[2].get_x(), my_points[2].get_y() ); |
|
115 xy<gdouble> center( my_points[1].get_x(), my_points[1].get_y() ); |
|
116 |
|
117 xy<gdouble> unit_vector_in_dir(target-center); |
|
118 // std::cout << target << " - " << center << " = " << unit_vector_in_dir << " / " <<unit_vector_in_dir.normSquare() ; |
|
119 unit_vector_in_dir/=sqrt( unit_vector_in_dir.normSquare() ); |
|
120 // std::cout << " = " << unit_vector_in_dir << std::endl; |
|
121 |
|
122 xy<gdouble> unit_norm_vector(0-unit_vector_in_dir.y, unit_vector_in_dir.x); |
|
123 // std::cout << unit_norm_vector << std::endl; |
|
124 |
|
125 { |
|
126 // /\ // top |
|
127 // / \ // |
|
128 // - - // c(enter)l(eft), ccl, ccr, cr |
|
129 // || // |
|
130 // || // b(ottom)l, br |
|
131 } |
|
132 |
|
133 double size=3; |
|
134 |
|
135 xy<gdouble> bl (center - unit_vector_in_dir * 3 * size + unit_norm_vector * size ); |
|
136 xy<gdouble> br (center - unit_vector_in_dir * 3 * size - unit_norm_vector * size ); |
|
137 xy<gdouble> ccl(center + unit_vector_in_dir * size + unit_norm_vector * size ); |
|
138 xy<gdouble> ccr(center + unit_vector_in_dir * size - unit_norm_vector * size ); |
|
139 xy<gdouble> cl (center + unit_vector_in_dir * size + unit_norm_vector * 2 * size ); |
|
140 xy<gdouble> cr (center + unit_vector_in_dir * size - unit_norm_vector * 2 * size ); |
|
141 xy<gdouble> top(center + unit_vector_in_dir * 3 * size); |
|
142 |
|
143 // std::cout << bl << " " << br << " " << ccl << " " << ccr << " " << cl << " " << cr << " " << top << std::endl; |
|
144 |
|
145 Gnome::Canvas::Points arrow_points; |
|
146 arrow_points.push_back(Gnome::Art::Point( bl.x , bl.y ) ); |
|
147 arrow_points.push_back(Gnome::Art::Point( br.x , br.y ) ); |
|
148 arrow_points.push_back(Gnome::Art::Point( ccr.x, ccr.y ) ); |
|
149 arrow_points.push_back(Gnome::Art::Point( cr.x , cr.y ) ); |
|
150 arrow_points.push_back(Gnome::Art::Point( top.x, top.y ) ); |
|
151 arrow_points.push_back(Gnome::Art::Point( cl.x , cl.y ) ); |
|
152 arrow_points.push_back(Gnome::Art::Point( ccl.x, ccl.y ) ); |
|
153 |
|
154 arrow->property_points().set_value(arrow_points); |
|
155 } |
|
156 } |
|
157 |
|
158 bool BrokenEdge::edgeFormerEventHandler(GdkEvent* e) |
|
159 { |
|
160 switch(e->type) |
|
161 { |
|
162 case GDK_BUTTON_PRESS: |
|
163 //we mark the location of the event to be able to calculate parameters of dragging |
|
164 if(gdc.getActualTool()!=CREATE_NODE) |
|
165 { |
|
166 gdc.toggleEdgeActivity(this, true); |
|
167 clicked_x=e->button.x; |
|
168 clicked_y=e->button.y; |
|
169 isbutton=true; |
|
170 } |
|
171 break; |
|
172 case GDK_BUTTON_RELEASE: |
|
173 if(gdc.getActualTool()!=CREATE_NODE) |
|
174 { |
|
175 gdc.toggleEdgeActivity(this, false); |
|
176 isbutton=false; |
|
177 } |
|
178 break; |
|
179 case GDK_MOTION_NOTIFY: |
|
180 //we only have to do sg. if the mouse button is pressed |
|
181 if(isbutton) |
|
182 { |
|
183 //new coordinates will be the old values, |
|
184 //because the item will be moved to the |
|
185 //new coordinate therefore the new movement |
|
186 //has to be calculated from here |
|
187 |
|
188 double dx=e->motion.x-clicked_x; |
|
189 double dy=e->motion.y-clicked_y; |
|
190 |
|
191 Gnome::Canvas::Points points_new; |
|
192 |
|
193 points_new.push_back(my_points[0]); |
|
194 points_new.push_back(my_points[1]=Gnome::Art::Point(my_points[1].get_x()+dx,my_points[1].get_y()+dy)); |
|
195 points_new.push_back(my_points[2]); |
|
196 |
|
197 setPoints(points_new); |
|
198 gdc.textReposition(xy<double>(my_points[1].get_x(),my_points[1].get_y())); |
|
199 |
|
200 clicked_x=e->motion.x; |
|
201 clicked_y=e->motion.y; |
|
202 |
|
203 } |
|
204 default: break; |
|
205 } |
|
206 |
|
207 return true; |
|
208 } |
|
209 |
|
210 xy<double> BrokenEdge::getArrowPos() |
|
211 { |
|
212 xy<double> ret_val(my_points[1].get_x(),my_points[1].get_y()); |
|
213 return ret_val; |
|
214 } |
|