1 #include "graph_displayer_canvas.h" |
1 #include "graph_displayer_canvas.h" |
2 #include <cmath> |
2 #include <cmath> |
3 |
3 |
4 GraphDisplayerCanvas::BrokenEdge::BrokenEdge(Gnome::Canvas::Group & g, Gnome::Canvas::Points p, GraphDisplayerCanvas & gc) : Line(g), gdc(gc), isbutton(false) |
4 GraphDisplayerCanvas::BrokenEdge::BrokenEdge(Gnome::Canvas::Group & g, Edge _edge, GraphDisplayerCanvas & gc) : Line(g), edge(_edge), gdc(gc), isbutton(false) |
5 { |
5 { |
6 my_points=new Gnome::Art::Point[3]; |
|
7 |
|
8 arrow=new Gnome::Canvas::Polygon(g); |
6 arrow=new Gnome::Canvas::Polygon(g); |
9 *arrow << Gnome::Canvas::Properties::fill_color("red"); |
7 *arrow << Gnome::Canvas::Properties::fill_color("red"); |
10 arrow->signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::BrokenEdge::edgeFormerEventHandler)); |
8 arrow->signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::BrokenEdge::edgeFormerEventHandler)); |
11 arrow->lower_to_bottom(); |
9 arrow->lower_to_bottom(); |
12 setPoints(p); |
10 draw(); |
13 } |
11 } |
14 |
12 |
15 GraphDisplayerCanvas::BrokenEdge::~BrokenEdge() |
13 GraphDisplayerCanvas::BrokenEdge::~BrokenEdge() |
16 { |
14 { |
17 if(arrow)delete(arrow); |
15 if(arrow)delete(arrow); |
18 } |
16 } |
19 |
17 |
20 void GraphDisplayerCanvas::BrokenEdge::setPoints(Gnome::Canvas::Points p, bool move) |
18 void GraphDisplayerCanvas::BrokenEdge::draw() |
21 { |
19 { |
22 bool set_arrow=false; |
20 MapStorage& ms = gdc.mytab.mapstorage; |
23 //red arrow losts its position-right button |
21 |
24 if(!move) |
22 // update the edge |
25 { |
23 { |
26 if(p.size()==2) |
24 Gnome::Canvas::Points points; |
27 { |
25 Node source = ms.graph.source(edge); |
28 set_arrow=true; |
26 Node target = ms.graph.target(edge); |
29 Gnome::Canvas::Points points_with_center; |
27 points.push_back(Gnome::Art::Point(ms.coords[source].x, |
30 points_with_center.push_back(my_points[0]=p[0]); |
28 ms.coords[source].y)); |
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 ); |
29 points.push_back(Gnome::Art::Point(ms.arrow_pos[edge].x, |
32 points_with_center.push_back(my_points[2]=p[1]); |
30 ms.arrow_pos[edge].y)); |
33 property_points().set_value(points_with_center); |
31 points.push_back(Gnome::Art::Point(ms.coords[target].x, |
34 } |
32 ms.coords[target].y)); |
35 if(p.size()==3) |
33 property_points().set_value(points); |
36 { |
34 } |
37 set_arrow=true; |
35 |
38 property_points().set_value(p); |
36 // update the arrow |
39 for(int i=0;i<3;i++) |
37 { |
40 { |
38 //calculating coordinates of the direction indicator arrow |
41 my_points[i]=p[i]; |
39 XY target(ms.coords[ms.graph.target(edge)]); |
42 } |
40 XY center(ms.arrow_pos[edge]); |
43 } |
41 |
|
42 XY unit_vector_in_dir(target-center); |
|
43 double length=sqrt( unit_vector_in_dir.normSquare() ); |
|
44 |
|
45 // std::cout << target << " - " << center << " = " << unit_vector_in_dir << " / " <<unit_vector_in_dir.normSquare() ; |
|
46 unit_vector_in_dir/=length; |
|
47 // std::cout << " = " << unit_vector_in_dir << std::endl; |
|
48 |
|
49 XY unit_norm_vector(0-unit_vector_in_dir.y, unit_vector_in_dir.x); |
|
50 // std::cout << unit_norm_vector << std::endl; |
|
51 |
|
52 { |
|
53 // /\ // top |
|
54 // / \ // |
|
55 // - - // c(enter)l(eft), ccl, ccr, cr |
|
56 // || // |
|
57 // || // b(ottom)l, br |
44 } |
58 } |
45 else |
|
46 { |
|
47 //arrow keeps its position-left button |
|
48 |
59 |
49 // if(p.size()==2) |
60 double size=3; |
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 |
61 |
62 ////////////////////////////////////////////////////////////////////////////////////////////////////// |
62 XY bl (center - unit_vector_in_dir * 3 * size + unit_norm_vector * size ); |
63 /////////// keeps shape-with scalar multiplication - version 2. |
63 XY br (center - unit_vector_in_dir * 3 * size - unit_norm_vector * size ); |
64 ////////////////////////////////////////////////////////////////////////////////////////////////////// |
64 XY ccl(center + unit_vector_in_dir * size + unit_norm_vector * size ); |
|
65 XY ccr(center + unit_vector_in_dir * size - unit_norm_vector * size ); |
|
66 XY cl (center + unit_vector_in_dir * size + unit_norm_vector * 2 * size ); |
|
67 XY cr (center + unit_vector_in_dir * size - unit_norm_vector * 2 * size ); |
|
68 XY top(center + unit_vector_in_dir * 3 * size); |
65 |
69 |
66 if(p.size()==2) |
70 //std::cout << bl << " " << br << " " << ccl << " " << ccr << " " << cl << " " << cr << " " << top << std::endl; |
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 |
71 |
73 double absa=sqrt(a_v.normSquare()); |
72 Gnome::Canvas::Points arrow_points; |
74 double absb=sqrt(b_v.normSquare()); |
73 arrow_points.push_back(Gnome::Art::Point( bl.x , bl.y ) ); |
|
74 arrow_points.push_back(Gnome::Art::Point( br.x , br.y ) ); |
|
75 arrow_points.push_back(Gnome::Art::Point( ccr.x, ccr.y ) ); |
|
76 arrow_points.push_back(Gnome::Art::Point( cr.x , cr.y ) ); |
|
77 arrow_points.push_back(Gnome::Art::Point( top.x, top.y ) ); |
|
78 arrow_points.push_back(Gnome::Art::Point( cl.x , cl.y ) ); |
|
79 arrow_points.push_back(Gnome::Art::Point( ccl.x, ccl.y ) ); |
75 |
80 |
76 if((absa!=0)&&(absb!=0)) |
81 arrow->property_points().set_value(arrow_points); |
77 { |
82 } |
78 //old vector from one node to the breakpoint - c |
|
79 xy<double> c_v(my_points[1].get_x()-my_points[0].get_x(),my_points[1].get_y()-my_points[0].get_y()); |
|
80 |
|
81 //unit vector with the same direction to a_v |
|
82 xy<double> a_v_u(a_v.x/absa,a_v.y/absa); |
|
83 |
|
84 //normal vector of unit vector with the same direction to a_v |
|
85 xy<double> a_v_u_n(((-1)*a_v_u.y),a_v_u.x); |
|
86 |
|
87 //unit vector with the same direction to b_v |
|
88 xy<double> b_v_u(b_v.x/absb,b_v.y/absb); |
|
89 |
|
90 //normal vector of unit vector with the same direction to b_v |
|
91 xy<double> b_v_u_n(((-1)*b_v_u.y),b_v_u.x); |
|
92 |
|
93 //vector c in a_v_u and a_v_u_n co-ordinate system |
|
94 xy<double> c_a(c_v*a_v_u,c_v*a_v_u_n); |
|
95 |
|
96 //new vector from one node to the breakpoint - d - we have to calculate this one |
|
97 xy<double> d_v=absb/absa*(c_a.x*b_v_u+c_a.y*b_v_u_n); |
|
98 |
|
99 my_points[1]=Gnome::Art::Point(d_v.x+p[0].get_x(),d_v.y+p[0].get_y()); |
|
100 |
|
101 my_points[0]=p[0]; |
|
102 my_points[2]=p[1]; |
|
103 |
|
104 Gnome::Canvas::Points points; |
|
105 for(int i=0;i<3;i++) |
|
106 { |
|
107 points.push_back(my_points[i]); |
|
108 } |
|
109 property_points().set_value(points); |
|
110 } |
|
111 else |
|
112 { |
|
113 //if distance is 0, segmentation would be occured |
|
114 //in calculations, because of division by zero |
|
115 //But we have luck: the edge cannot be seen in |
|
116 //this case, so no update needed |
|
117 set_arrow=false; |
|
118 } |
|
119 } |
|
120 } |
|
121 if(set_arrow) |
|
122 { |
|
123 //calculating coordinates of the direction indicator arrow |
|
124 |
|
125 xy<gdouble> target( my_points[2].get_x(), my_points[2].get_y() ); |
|
126 xy<gdouble> center( my_points[1].get_x(), my_points[1].get_y() ); |
|
127 |
|
128 xy<gdouble> unit_vector_in_dir(target-center); |
|
129 double length=sqrt( unit_vector_in_dir.normSquare() ); |
|
130 |
|
131 // std::cout << target << " - " << center << " = " << unit_vector_in_dir << " / " <<unit_vector_in_dir.normSquare() ; |
|
132 unit_vector_in_dir/=length; |
|
133 // std::cout << " = " << unit_vector_in_dir << std::endl; |
|
134 |
|
135 xy<gdouble> unit_norm_vector(0-unit_vector_in_dir.y, unit_vector_in_dir.x); |
|
136 // std::cout << unit_norm_vector << std::endl; |
|
137 |
|
138 { |
|
139 // /\ // top |
|
140 // / \ // |
|
141 // - - // c(enter)l(eft), ccl, ccr, cr |
|
142 // || // |
|
143 // || // b(ottom)l, br |
|
144 } |
|
145 |
|
146 double size=3; |
|
147 |
|
148 xy<gdouble> bl (center - unit_vector_in_dir * 3 * size + unit_norm_vector * size ); |
|
149 xy<gdouble> br (center - unit_vector_in_dir * 3 * size - unit_norm_vector * size ); |
|
150 xy<gdouble> ccl(center + unit_vector_in_dir * size + unit_norm_vector * size ); |
|
151 xy<gdouble> ccr(center + unit_vector_in_dir * size - unit_norm_vector * size ); |
|
152 xy<gdouble> cl (center + unit_vector_in_dir * size + unit_norm_vector * 2 * size ); |
|
153 xy<gdouble> cr (center + unit_vector_in_dir * size - unit_norm_vector * 2 * size ); |
|
154 xy<gdouble> top(center + unit_vector_in_dir * 3 * size); |
|
155 |
|
156 //std::cout << bl << " " << br << " " << ccl << " " << ccr << " " << cl << " " << cr << " " << top << std::endl; |
|
157 |
|
158 Gnome::Canvas::Points arrow_points; |
|
159 arrow_points.push_back(Gnome::Art::Point( bl.x , bl.y ) ); |
|
160 arrow_points.push_back(Gnome::Art::Point( br.x , br.y ) ); |
|
161 arrow_points.push_back(Gnome::Art::Point( ccr.x, ccr.y ) ); |
|
162 arrow_points.push_back(Gnome::Art::Point( cr.x , cr.y ) ); |
|
163 arrow_points.push_back(Gnome::Art::Point( top.x, top.y ) ); |
|
164 arrow_points.push_back(Gnome::Art::Point( cl.x , cl.y ) ); |
|
165 arrow_points.push_back(Gnome::Art::Point( ccl.x, ccl.y ) ); |
|
166 |
|
167 arrow->property_points().set_value(arrow_points); |
|
168 } |
|
169 } |
83 } |
170 |
84 |
171 bool GraphDisplayerCanvas::BrokenEdge::edgeFormerEventHandler(GdkEvent* e) |
85 bool GraphDisplayerCanvas::BrokenEdge::edgeFormerEventHandler(GdkEvent* e) |
172 { |
86 { |
173 switch(e->type) |
87 switch(e->type) |