-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy patheditshapeitem.cpp
More file actions
228 lines (192 loc) · 5.37 KB
/
editshapeitem.cpp
File metadata and controls
228 lines (192 loc) · 5.37 KB
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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
#include "editshapeitem.h"
EditShapeItem::EditShapeItem(QString title)
{
if(title=="") title="item1";
this->setTitle(title);
m_closed=false;
}
void EditShapeItem::insertPoint(QPointF p)
{
if(m_closed)
{
pointList.clear();
m_closed=false;
}
pointList+=p;
}
void EditShapeItem::clear()
{
pointList.clear();
m_closed=false;
}
QPolygonF EditShapeItem::getPolygon()
{
return pointList;
}
void EditShapeItem::init(QwtPlot *plot ,QColor color,int id,ShapeType type)
{
QColor fillColor = color;
fillColor.setAlpha( 25 );
QPen pen( color, 3 );
pen.setJoinStyle( Qt::MiterJoin );
this->setPen( pen );
this->setBrush( fillColor );
QString str=this->title().text();
str+=QString::number(id,10);
this->setTitle(str);
this->attach(plot);
this->plot=plot;
this->m_color=color;
this->m_id=id;
this->m_type=type;
}
void EditShapeItem::setAlpha(int a)
{
QColor fillColor = this->m_color;
fillColor.setAlpha( a );
this->setBrush( fillColor );
}
void EditShapeItem::setShapeItem()
{
QPainterPath path;
path.addPolygon(pointList);
this->setShape( path );
}
void EditShapeItem::setShapeItemEnd()
{
QPainterPath path;
if(pointList.size()<3) return;
pointList.append(pointList.at(0));
path.addPolygon(pointList);
this->setShape( path );
this->setItemAttribute( QwtPlotItem::Legend, true );
this->setLegendMode( QwtPlotShapeItem::LegendShape );
this->setLegendIconSize( QSize( 20, 20 ) );
this->setRenderHint( QwtPlotItem::RenderAntialiased, true );
this->detach();
this->attach(plot);
m_closed=true;
}
void EditShapeItem::setId(int id)
{
this->m_id=id;
}
void EditShapeItem::setType(ShapeType type)
{
this->m_type=type;
}
int EditShapeItem::id()
{
return this->m_id;
}
EditShapeItem::ShapeType EditShapeItem::type()
{
return this->m_type;
}
bool EditShapeItem::closed()
{
return this->m_closed;
}
void EditShapeItem::setClose(bool closed)
{
this->m_closed = closed;
}
bool EditShapeItem::pointInPolygon(QPointF point)
{
QPolygonF& polygon =pointList;
int polySides = polygon.size()-1;
if(polySides<4) return false; //last point is the same as first
int i,j=polySides-1 ;
bool oddNodes=false ;//0 -- not in z
float x=point.x();
float y=point.y();
for (i=0;i<polySides; i++) {
// qDebug() << " pointInPolygon "<<QString::number(i,10)<<" "<<QString::number(polygon.at(i).x(),'f',3)<<" "
// <<" "<<QString::number(polygon.at(i).y(),'f',3);
if(((polygon.at(i).y()< y && polygon.at(j).y()>=y)
|| (polygon.at(j).y()< y && polygon.at(i).y()>=y))
&& (polygon.at(i).x()<=x || polygon.at(j).x()<=x)) {
oddNodes^=(polygon.at(i).x()+(y-polygon.at(i).y())/(polygon.at(j).y()-polygon.at(i).y())*(polygon.at(j).x()-polygon.at(i).x())<x);}
j=i;}
return oddNodes;
}
bool EditShapeItem::segmentsIntr(RobotPoint a, RobotPoint b, RobotPoint c, RobotPoint d,RobotPoint &out){
// 三角形abc 面积的2倍
double area_abc = (a.x - c.x) * (b.y - c.y) - (a.y - c.y) * (b.x - c.x);
// 三角形abd 面积的2倍
double area_abd = (a.x - d.x) * (b.y - d.y) - (a.y - d.y) * (b.x - d.x);
// 面积符号相同则两点在线段同侧,不相交 (对点在线段上的情况,本例当作不相交处理);
if ( area_abc*area_abd>=0 ) {
return false;
}
// 三角形cda 面积的2倍
double area_cda = (c.x - a.x) * (d.y - a.y) - (c.y - a.y) * (d.x - a.x);
// 三角形cdb 面积的2倍
// 注意: 这里有一个小优化.不需要再用公式计算面积,而是通过已知的三个面积加减得出.
double area_cdb = area_cda + area_abc - area_abd ;
if ( area_cda * area_cdb >= 0 ) {
return false;
}
//计算交点坐标
double t = area_cda / ( area_abd- area_abc );
double dx= t*(b.x - a.x);
double dy= t*(b.y - a.y);
out.x=a.x + dx;
out.y=a.y + dy;
return true;
}
bool EditShapeItem::pointToPolygonDis(RobotPoint pose,double &dis)
{
QPolygonF& polygon =pointList;
RobotPoint aa,bb,cc,dd,off;
off.x=100;
off.y=0;
off.phi=0;
aa=pose;
bb=aa+off;
for(int i=0;i<polygon.size()-1;i++)
{
cc.x=polygon.at(i).x();
cc.y=polygon.at(i).y();
dd.x=polygon.at(i+1).x();
dd.y=polygon.at(i+1).y();
//bool ret = intersect(aa,bb,cc,dd);
//if(ret==true)
{
RobotPoint out;
bool ret = segmentsIntr(aa,bb,cc,dd,out);
if(ret)
{
double x=aa.x-out.x;
double y=aa.y-out.y;
dis=sqrt(x*x+y*y);
return true;
}
}
}
return false;
}
///------------alg 3------------
double EditShapeItem::determinant(double v1, double v2, double v3, double v4) // 行列式
{
return (v1*v3-v2*v4);
}
bool EditShapeItem::intersect(RobotPoint aa, RobotPoint bb, RobotPoint cc, RobotPoint dd)
{
double delta = determinant(bb.x-aa.x, cc.x-dd.x, bb.y-aa.y, cc.y-dd.y);
if ( delta<=(1e-6) && delta>=-(1e-6) ) // delta=0,表示两线段重合或平行
{
return false;
}
double namenda = determinant(cc.x-aa.x, cc.x-dd.x, cc.y-aa.y, cc.y-dd.y) / delta;
if ( namenda>1 || namenda<0 )
{
return false;
}
double miu = determinant(bb.x-aa.x, cc.x-aa.x, bb.y-aa.y, cc.y-aa.y) / delta;
if ( miu>1 || miu<0 )
{
return false;
}
return true;
}