Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
M
map-parent
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
常超
map-parent
Commits
2dcc5362
Commit
2dcc5362
authored
Dec 13, 2022
by
yangyang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
轨迹相似度工具提交(标准)
parent
0e34e70e
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
562 additions
and
0 deletions
+562
-0
common/common_utils/src/main/java/com/founder/commonutils/util/map/Coordinate.java
+13
-0
common/common_utils/src/main/java/com/founder/commonutils/util/map/DTW.java
+112
-0
common/common_utils/src/main/java/com/founder/commonutils/util/map/LCSS.java
+81
-0
common/common_utils/src/main/java/com/founder/commonutils/util/map/LocalPath.java
+356
-0
No files found.
common/common_utils/src/main/java/com/founder/commonutils/util/map/Coordinate.java
0 → 100644
View file @
2dcc5362
package
com
.
founder
.
commonutils
.
util
.
map
;
import
lombok.AllArgsConstructor
;
import
lombok.Data
;
import
lombok.NoArgsConstructor
;
@Data
@AllArgsConstructor
@NoArgsConstructor
public
class
Coordinate
{
private
double
x
;
private
double
y
;
}
common/common_utils/src/main/java/com/founder/commonutils/util/map/DTW.java
0 → 100644
View file @
2dcc5362
package
com
.
founder
.
commonutils
.
util
.
map
;
import
java.text.DecimalFormat
;
import
java.util.Arrays
;
import
java.util.List
;
public
class
DTW
{
//一维比较
//s1 = [1, 2, 3, 4, 5, 5, 5, 4]
//s2 = [3, 4, 5, 5, 5, 4]
public
void
DTW_1
(
int
[]
s1
,
int
[]
s2
)
{
int
r
=
s1
.
length
;
int
c
=
s2
.
length
;
//计算距离矩阵M
int
[][]
D0
=
new
int
[
r
+
1
][
c
+
1
];
for
(
int
i
=
0
;
i
<
r
+
1
;
i
++)
{
for
(
int
j
=
0
;
j
<
c
+
1
;
j
++)
{
if
(
i
==
0
&&
j
==
0
)
{
D0
[
i
][
j
]
=
0
;
}
else
if
(
i
==
0
)
{
D0
[
i
][
j
]
=
Integer
.
MAX_VALUE
;
}
else
if
(
j
==
0
)
{
D0
[
i
][
j
]
=
Integer
.
MAX_VALUE
;
}
else
{
D0
[
i
][
j
]
=
Math
.
abs
(
s1
[
i
-
1
]
-
s2
[
j
-
1
]);
}
}
}
int
[][]
D
=
new
int
[
r
][
c
];
for
(
int
i
=
0
;
i
<
r
;
i
++)
{
for
(
int
j
=
0
;
j
<
c
;
j
++)
{
D
[
i
][
j
]
=
D0
[
i
+
1
][
j
+
1
];
}
}
System
.
out
.
println
(
"距离矩阵D:"
);
System
.
out
.
println
(
Arrays
.
deepToString
(
D
).
replaceAll
(
"],"
,
"],"
+
System
.
getProperty
(
"line.separator"
)));
//计算损失矩阵M
int
[][]
MC
=
D0
.
clone
();
for
(
int
i
=
1
;
i
<
r
+
1
;
i
++)
{
for
(
int
j
=
1
;
j
<
c
+
1
;
j
++)
{
MC
[
i
][
j
]
+=
Math
.
min
(
Math
.
min
(
MC
[
i
-
1
][
j
-
1
],
MC
[
i
][
j
-
1
]),
MC
[
i
-
1
][
j
]);
}
}
int
[][]
M
=
new
int
[
r
][
c
];
for
(
int
i
=
0
;
i
<
r
;
i
++)
{
for
(
int
j
=
0
;
j
<
c
;
j
++)
{
M
[
i
][
j
]
=
MC
[
i
+
1
][
j
+
1
];
}
}
System
.
out
.
println
(
"损失矩阵M:"
);
System
.
out
.
println
(
Arrays
.
deepToString
(
M
).
replaceAll
(
"],"
,
"],"
+
System
.
getProperty
(
"line.separator"
)));
System
.
out
.
println
(
"序列距离:"
+
M
[
r
-
1
][
c
-
1
]);
}
public
static
double
getDistance
(
Coordinate
p
,
Coordinate
q
)
{
double
dx
=
p
.
getX
()
-
q
.
getX
();
double
dy
=
p
.
getY
()
-
q
.
getY
();
double
distance
=
Math
.
sqrt
(
dx
*
dx
+
dy
*
dy
);
return
distance
;
}
public
void
DTW_2
(
List
<
Coordinate
>
coords1
,
List
<
Coordinate
>
coords2
)
{
int
r
=
coords1
.
size
();
int
c
=
coords2
.
size
();
//计算距离矩阵M
double
[][]
D0
=
new
double
[
r
+
1
][
c
+
1
];
for
(
int
i
=
0
;
i
<
r
+
1
;
i
++)
{
for
(
int
j
=
0
;
j
<
c
+
1
;
j
++)
{
if
(
i
==
0
&&
j
==
0
)
{
D0
[
i
][
j
]
=
0
;
}
else
if
(
i
==
0
)
{
D0
[
i
][
j
]
=
Double
.
MAX_VALUE
;
}
else
if
(
j
==
0
)
{
D0
[
i
][
j
]
=
Double
.
MAX_VALUE
;
}
else
{
// D0[i][j] = coords1.get(i - 1).distance(coords2.get(j - 1));
D0
[
i
][
j
]
=
getDistance
(
coords1
.
get
(
i
-
1
),
coords2
.
get
(
j
-
1
));
}
}
}
DecimalFormat
df
=
new
DecimalFormat
(
"#.00"
);
double
[][]
D
=
new
double
[
r
][
c
];
for
(
int
i
=
0
;
i
<
r
;
i
++)
{
for
(
int
j
=
0
;
j
<
c
;
j
++)
{
D
[
i
][
j
]
=
Double
.
parseDouble
(
df
.
format
(
D0
[
i
+
1
][
j
+
1
]));
}
}
System
.
out
.
println
(
"距离矩阵D:"
);
System
.
out
.
println
(
Arrays
.
deepToString
(
D
).
replaceAll
(
"],"
,
"],"
+
System
.
getProperty
(
"line.separator"
)));
//计算损失矩阵M
double
[][]
MC
=
D0
.
clone
();
for
(
int
i
=
1
;
i
<
r
+
1
;
i
++)
{
for
(
int
j
=
1
;
j
<
c
+
1
;
j
++)
{
MC
[
i
][
j
]
+=
Math
.
min
(
Math
.
min
(
MC
[
i
-
1
][
j
-
1
],
MC
[
i
][
j
-
1
]),
MC
[
i
-
1
][
j
]);
}
}
double
[][]
M
=
new
double
[
r
][
c
];
for
(
int
i
=
0
;
i
<
r
;
i
++)
{
for
(
int
j
=
0
;
j
<
c
;
j
++)
{
M
[
i
][
j
]
=
MC
[
i
+
1
][
j
+
1
];
}
}
System
.
out
.
println
(
"损失矩阵M:"
);
System
.
out
.
println
(
Arrays
.
deepToString
(
M
).
replaceAll
(
"],"
,
"],"
+
System
.
getProperty
(
"line.separator"
)));
System
.
out
.
println
(
"序列距离:"
+
M
[
r
-
1
][
c
-
1
]);
}
}
\ No newline at end of file
common/common_utils/src/main/java/com/founder/commonutils/util/map/LCSS.java
0 → 100644
View file @
2dcc5362
package
com
.
founder
.
commonutils
.
util
.
map
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.List
;
public
class
LCSS
{
private
List
<
Coordinate
>
l1
;
private
List
<
Coordinate
>
l2
;
private
List
<
Coordinate
>
lcs
=
new
ArrayList
<>();
public
static
double
getDistance
(
Coordinate
p
,
Coordinate
q
)
{
double
dx
=
p
.
getX
()
-
q
.
getX
();
double
dy
=
p
.
getY
()
-
q
.
getY
();
double
distance
=
Math
.
sqrt
(
dx
*
dx
+
dy
*
dy
);
return
distance
;
}
public
boolean
isNearby
(
Coordinate
a
,
Coordinate
b
,
int
radius
)
{
if
(
getDistance
(
a
,
b
)
<
radius
)
return
true
;
return
false
;
}
public
void
printLcs
(
int
[][]
flag
,
List
<
Coordinate
>
a
,
int
i
,
int
j
)
{
if
(
i
==
0
||
j
==
0
)
return
;
if
(
flag
[
i
][
j
]
==
1
)
{
printLcs
(
flag
,
a
,
i
-
1
,
j
-
1
);
lcs
.
add
(
a
.
get
(
i
-
1
));
}
else
if
(
flag
[
i
][
j
]
==
2
)
{
printLcs
(
flag
,
a
,
i
,
j
-
1
);
}
else
{
printLcs
(
flag
,
a
,
i
-
1
,
j
);
}
}
public
double
lcs
(
List
<
Coordinate
>
l1
,
List
<
Coordinate
>
l2
,
int
radius
)
{
int
len1
=
l1
.
size
();
int
len2
=
l2
.
size
();
int
[][]
c
=
new
int
[
len1
+
1
][
len2
+
1
];
int
[][]
flag
=
new
int
[
len1
+
1
][
len2
+
1
];
for
(
int
i
=
0
;
i
<
len1
;
i
++)
{
for
(
int
j
=
0
;
j
<
len2
;
j
++)
{
if
(
isNearby
(
l1
.
get
(
i
),
l2
.
get
(
j
),
radius
))
{
c
[
i
+
1
][
j
+
1
]
=
c
[
i
][
j
]
+
1
;
flag
[
i
+
1
][
j
+
1
]
=
1
;
//1='ok' //1表示箭头为 左上
//for循环知道行数列数的情况
//System.out.print(flag[i + 1][j + 1] + " ");
}
else
if
(
c
[
i
+
1
][
j
]
>
c
[
i
][
j
+
1
])
{
c
[
i
+
1
][
j
+
1
]
=
c
[
i
+
1
][
j
];
flag
[
i
+
1
][
j
+
1
]
=
2
;
//2='left' //2表示箭头向 上
//for循环知道行数列数的情况
//System.out.print(flag[i + 1][j + 1] + " ");
}
else
{
c
[
i
+
1
][
j
+
1
]
=
c
[
i
][
j
+
1
];
flag
[
i
+
1
][
j
+
1
]
=
3
;
//3='up' //3表示箭头向 左
//for循环知道行数列数的情况
//System.out.print(flag[i + 1][j + 1] + " ");
}
}
}
printLcs
(
flag
,
l1
,
len1
,
len2
);
//归一化处理
return
(
lcs
.
size
()
*
1.0
/
Math
.
min
(
len1
,
len2
));
}
public
static
void
main
(
String
[]
args
)
{
List
<
Coordinate
>
l1
=
new
ArrayList
<>();
l1
.
add
(
new
Coordinate
(
114.300
,
30.1
));
l1
.
add
(
new
Coordinate
(
114.302
,
30.101
));
/* l1.add(new Coordinate(114.3023, 30.1002));
l1.add(new Coordinate(114.30235, 30.1011));
l1.add(new Coordinate(114.304, 30.1003));*/
List
<
Coordinate
>
l2
=
new
ArrayList
<>();
l2
.
add
(
new
Coordinate
(
109.304
,
30.1003
));
l2
.
add
(
new
Coordinate
(
109.302
,
30.101
));
LCSS
lcss
=
new
LCSS
();
System
.
out
.
println
(
lcss
.
lcs
(
l1
,
l2
,
10
));
}
}
\ No newline at end of file
common/common_utils/src/main/java/com/founder/commonutils/util/map/LocalPath.java
0 → 100644
View file @
2dcc5362
package
com
.
founder
.
commonutils
.
util
.
map
;
/**
* 艮
* 2022/1/18
* 10:54
*/
import
java.util.*
;
/**
* _ooOoo_
* o8888888o
* 88" . "88
* (| -_- |)
* O\ = /O
* ___/`---'\____
* . ' \\| |// `.
* / \\||| : |||// \
* / _||||| -:- |||||- \
* | | \\\ - /// | |
* | \_| ''\---/'' | |
* \ .-\__ `-` ___/-. /
* ___`. .' /--.--\ `. . __
* ."" '< `.___\_<|>_/___.' >'"".
* | | : `- \`.;`\ _ /`;.`/ - ` : | |
* \ \ `-. \_ __\ /__ _/ .-` / /
* ======`-.____`-.___\_____/___.-`____.-'======
* `=---='
*/
public
class
LocalPath
{
public
static
void
main
(
String
[]
args
)
{
Double
[]
s1
=
{
1.0
,
1.0
};
Double
[]
s2
=
{
1.0
,
2.0
};
Double
[]
s3
=
{
2.0
,
3.0
};
Double
[]
s4
=
{
2.0
,
4.0
};
Double
[]
s5
=
{
3.0
,
4.5
};
Double
[]
s6
=
{
3.0
,
4.0
};
Solution
s
=
new
Solution
();
//System.out.println(s.onSegment(s1, s2, s3));
List
<
Double
[]>
l
=
new
ArrayList
<>();
List
<
Double
[]>
l2
=
new
ArrayList
<>();
l
.
add
(
s1
);
l
.
add
(
s2
);
l
.
add
(
s3
);
l
.
add
(
s4
);
l
.
add
(
s5
);
l
.
add
(
s6
);
l2
.
add
(
new
Double
[]{
1.0
,
1.0
});
l2
.
add
(
new
Double
[]{
1.0
,
2.0
});
l2
.
add
(
new
Double
[]{
2.0
,
2.5
});
l2
.
add
(
new
Double
[]{
2.0
,
3.5
});
l2
.
add
(
new
Double
[]{
3.0
,
3.5
});
l2
.
add
(
new
Double
[]{
3.0
,
4.0
});
// List<Double[]> l3 = new ArrayList<>();
// List<Double[]> l4 = new ArrayList<>();
// l3.add(new Double[]{3.0, 3.5});
// l3.add(new Double[]{3.0, 4.0});
// l4.add(new Double[]{3.0, 4.5});
// l4.add(new Double[]{3.0, 4.0});
//// l2.add(new Double[]{3.0, 3.5});
//// l2.add(new Double[]{3.0, 4.0});
// Double[] i = s.intersection(l3.get(0), l3.get(1), l4.get(0), l4.get(1));
// for (Double aDouble : i) {
// System.out.println(aDouble);
// }
List
<
Double
[]>
doubles
=
s
.
intersectionAsList
(
l
,
l2
);
System
.
out
.
println
(
s
.
area
(
doubles
,
l
,
l2
));
}
}
class
Solution
{
//计算交点及上一个交点的面积
//得到一个集合里面存储全部的交点面积
public
double
area
(
List
<
Double
[]>
in
,
List
<
Double
[]>
path1
,
List
<
Double
[]>
path2
)
{
//得到交点的,路径
Double
[]
d1
,
d2
;
double
l1
=
0.0
,
l2
=
0.0
;
double
lip
=
0.0
;
List
<
Double
[]>
d3
=
new
ArrayList
<>();
List
<
Double
[]>
d4
=
new
ArrayList
<>();
List
<
Double
[]>
d5
=
new
ArrayList
<>();
List
<
Double
[]>
d6
=
new
ArrayList
<>();
List
<
Double
[]>
power
=
new
ArrayList
<>();
List
<
Double
[]>
power2
=
new
ArrayList
<>();
for
(
int
i
=
1
;
i
<
path1
.
size
();
i
++)
{
//路径1的长度
l1
=
Math
.
sqrt
(
Math
.
pow
(
path1
.
get
(
i
)[
0
]
-
path1
.
get
(
i
-
1
)[
0
],
2
)
+
Math
.
pow
(
path1
.
get
(
i
)[
1
]
-
path1
.
get
(
i
-
1
)[
1
],
2
))
+
l1
;
}
System
.
out
.
println
(
"路径s的长度为:"
+
l1
);
for
(
int
i
=
1
;
i
<
path2
.
size
();
++
i
)
{
//路径2的长度
l2
=
Math
.
sqrt
(
Math
.
pow
(
path2
.
get
(
i
)[
0
]
-
path2
.
get
(
i
-
1
)[
0
],
2
)
+
Math
.
pow
(
path2
.
get
(
i
)[
1
]
-
path2
.
get
(
i
-
1
)[
1
],
2
))
+
l2
;
}
System
.
out
.
println
(
"路径q的长度为:"
+
l2
);
if
(
in
.
size
()
<
2
)
{
return
0.0
;
}
for
(
int
i
=
1
;
i
<
in
.
size
();
i
++)
{
System
.
out
.
println
(
"======================================="
);
//从二个交点的时候,可以得到面积
//i ,i-1
d1
=
in
.
get
(
i
);
//第二个交点
d2
=
in
.
get
(
i
-
1
);
//第一个交点
//两个容器,一个用来判断,一个用来装载
d4
.
clear
();
d6
.
clear
();
// //找到路径12中在范围d1,d2的
int
min
=
Math
.
min
(
path1
.
size
(),
path2
.
size
());
//开始位置为上一个交点,
for
(
int
i1
=
d3
.
size
();
i1
<
path1
.
size
();
i1
++)
{
//判断交点在哪条路径上,得到对应的点的范围
if
(!
Arrays
.
equals
(
path1
.
get
(
i1
),
d1
))
{
d3
.
add
(
path1
.
get
(
i1
));
d4
.
add
(
path1
.
get
(
i1
));
}
if
(
Arrays
.
equals
(
path1
.
get
(
i1
),
d1
))
{
break
;
}
}
for
(
int
i1
=
d5
.
size
();
i1
<
path2
.
size
();
++
i1
)
{
//判断交点在哪条路径上,得到对应的点的范围
if
(!
Arrays
.
equals
(
path2
.
get
(
i1
),
d1
))
{
d5
.
add
(
path2
.
get
(
i1
));
d6
.
add
(
path2
.
get
(
i1
));
}
if
(
Arrays
.
equals
(
path2
.
get
(
i1
),
d1
))
{
break
;
}
}
d4
.
add
(
d1
);
d6
.
add
(
d1
);
System
.
out
.
println
(
"交点范围坐标:["
+
d2
[
0
]
+
" "
+
d2
[
1
]
+
"]"
+
"["
+
d1
[
0
]
+
" "
+
d1
[
1
]
+
"]"
);
System
.
out
.
println
(
"交点范围内路径d4的点:"
);
d4
.
forEach
(
a
->
{
System
.
out
.
println
(
"["
+
a
[
0
]
+
" "
+
a
[
1
]
+
"]"
);
});
System
.
out
.
println
(
"交点范围内路径d6的点:"
);
d6
.
forEach
(
a
->
{
System
.
out
.
println
(
"["
+
a
[
0
]
+
" "
+
a
[
1
]
+
"]"
);
});
//这个时候我们有全部的点,带入公式得到对应范围的面积,进行存储
double
aread4
=
0.0
;
double
aread6
=
0.0
;
//计算此时d4,d6的面积,相加
for
(
int
j
=
0
;
j
<
d4
.
size
();
j
++)
{
//多边形面积方程
if
(
j
==
d4
.
size
()
-
1
)
{
aread4
=
0.5
*
(
d4
.
get
(
j
)[
0
]
*
d4
.
get
(
0
)[
1
]
-
d4
.
get
(
0
)[
0
]
*
d4
.
get
(
j
)[
1
])
+
aread4
;
}
else
{
aread4
=
0.5
*
(
d4
.
get
(
j
)[
0
]
*
d4
.
get
(
j
+
1
)[
1
]
-
d4
.
get
(
j
+
1
)[
0
]
*
d4
.
get
(
j
)[
1
])
+
aread4
;
}
//System.out.println(area);
}
for
(
int
j
=
0
;
j
<
d6
.
size
();
++
j
)
{
//多边形面积方程
if
(
j
==
d6
.
size
()
-
1
)
{
aread6
=
0.5
*
(
d6
.
get
(
j
)[
0
]
*
d6
.
get
(
0
)[
1
]
-
d6
.
get
(
0
)[
0
]
*
d6
.
get
(
j
)[
1
])
+
aread6
;
}
else
{
aread6
=
0.5
*
(
d6
.
get
(
j
)[
0
]
*
d6
.
get
(
j
+
1
)[
1
]
-
d6
.
get
(
j
+
1
)[
0
]
*
d6
.
get
(
j
)[
1
])
+
aread6
;
}
//System.out.println(area);
}
//area表示面积
double
area
=
Math
.
abs
(
aread4
)
+
Math
.
abs
(
aread6
);
System
.
out
.
println
(
"第"
+
i
+
"交点到"
+
(
i
+
1
)
+
"交点范围面积:"
+
area
);
//求交点权重
power
.
addAll
(
d4
);
double
ps
=
0.0
,
pq
=
0.0
,
p
;
//路径s的路径
for
(
int
j
=
1
;
j
<
power
.
size
();
j
++)
{
ps
=
Math
.
sqrt
(
Math
.
pow
(
power
.
get
(
j
)[
0
]
-
power
.
get
(
j
-
1
)[
0
],
2
)
+
Math
.
pow
(
power
.
get
(
j
)[
1
]
-
power
.
get
(
j
-
1
)[
1
],
2
))
+
ps
;
}
power2
.
addAll
(
d6
);
for
(
int
j
=
1
;
j
<
power2
.
size
();
++
j
)
{
pq
=
Math
.
sqrt
(
Math
.
pow
(
power2
.
get
(
j
)[
0
]
-
power2
.
get
(
j
-
1
)[
0
],
2
)
+
Math
.
pow
(
power2
.
get
(
j
)[
1
]
-
power2
.
get
(
j
-
1
)[
1
],
2
))
+
pq
;
}
//权重
p
=
(
pq
+
ps
)
/
(
l1
+
l2
);
System
.
out
.
println
(
"第"
+
i
+
"交点到"
+
(
i
+
1
)
+
"交点范围的权重:"
+
p
);
lip
=
lip
+
p
*
area
;
power
.
clear
();
power2
.
clear
();
}
//返回所有面积和周长权重的map集合.
System
.
out
.
println
(
"最后的dLIP为"
+
Math
.
abs
(
lip
));
// System.out.println("轨迹相似度为:"+Math.abs(lip)*100+"%");
// System.out.println("轨迹相似度为:"+Math.abs(lip)/2.3*100+"%");
// System.out.println("轨迹相似度为:"+Math.abs(lip)*100+"%");
// System.out.println("轨迹相似度为:"+Math.abs(lip)/2*100+"%");
// System.out.println("轨迹相似度为:"+Math.abs(lip)/5*100+"%");
return
lip
;
}
//将所有的点存储在一个Set集合,下标0标识起点,后面的每一个的点的起点都是前面的终点
//因为我们不知道所有线段长度的情况,依次遍历每一条线段所有情况得到所有交点,
//以起点为目标,得到每个交点与之对应的上一个交点的情况
public
List
<
Double
[]>
intersectionAsList
(
List
<
Double
[]>
path1
,
List
<
Double
[]>
path2
)
{
//交点集合
int
h
=
0
;
Double
[]
intersection
=
new
Double
[
0
];
List
<
Double
[]>
list
=
new
ArrayList
<>();
int
min
=
Math
.
min
(
path1
.
size
(),
path2
.
size
());
int
max
=
Math
.
max
(
path1
.
size
(),
path2
.
size
());
for
(
int
i
=
1
;
i
<
min
;
i
++)
{
//如果与上一条相交,则不用考虑多余情况
for
(
int
j
=
1
;
j
<
max
;
j
++)
{
//判断第i与第j是否相交,相交的话,存入到list
// System.out.println(intersection[0] + " " + intersection[1]);
//在比较最后一个的时候,发生了数组越界
// System.out.println("进行比较的线段s[" + path1.get(i - 1)[0] + path1.get(i - 1)[1] + "][" + path1.get(i)[0] + path1.get(i)[1] + "]");
// System.out.println("进行比较的线段q[" + path2.get(j - 1)[0] + path2.get(j - 1)[1] + "][" + path2.get(j)[0] + path2.get(j)[1] + "]");
try
{
intersection
=
intersection
(
path1
.
get
(
i
-
1
),
path1
.
get
(
i
),
path2
.
get
(
j
),
path2
.
get
(
j
-
1
));
}
catch
(
Exception
e
)
{
//e.printStackTrace();
}
//System.out.println(intersection[0] + " " + intersection[1]);
if
(
intersection
!=
null
&&
!
list
.
contains
(
intersection
)
&&
intersection
.
length
>
0
)
{
//System.out.println(intersection);
list
.
add
(
intersection
);
}
}
}
isEquality
(
list
);
int
si
=
1
;
int
si2
=
1
;
int
size
=
path1
.
size
();
for
(
int
i
=
1
;
i
<
path1
.
size
();
i
++)
{
for
(
Double
[]
doubles
:
list
)
{
//将交点添加到路径,保证每次都是最新的路径
if
(
onSegment
(
path1
.
get
(
i
-
1
),
path1
.
get
(
i
),
doubles
))
{
i
++;
path1
.
add
(
si
,
doubles
);
}
si
=
i
;
}
}
for
(
int
i
=
1
;
i
<
path2
.
size
();
i
++)
{
for
(
Double
[]
doubles
:
list
)
{
//将交点添加到路径,保证每次都是最新的路径
if
(
onSegment
(
path2
.
get
(
i
-
1
),
path2
.
get
(
i
),
doubles
))
{
i
++;
path2
.
add
(
si2
,
doubles
);
//i--;
}
si2
=
i
;
}
}
for
(
Double
[]
doubles
:
list
)
{
System
.
out
.
println
(
"交点坐标:["
+
doubles
[
0
]
+
" "
+
doubles
[
1
]
+
"]"
);
}
isEquality
(
path1
);
isEquality
(
path2
);
return
list
;
}
//判断集合内数组是否相等,去重
public
void
isEquality
(
List
<
Double
[]>
list
)
{
boolean
isArray
=
false
;
for
(
int
i
=
0
;
i
<
list
.
size
();
i
++)
{
for
(
int
j
=
i
+
1
;
j
<
list
.
size
();
j
++)
{
boolean
equals
=
Arrays
.
equals
(
list
.
get
(
i
),
list
.
get
(
j
));
//相等情况下判断,但是下标remove以后,list会前进
if
(
equals
)
{
list
.
remove
(
j
);
j
--;
}
}
}
}
Double
[]
ans
;
//判断点是否在线段上
//0,横坐标,1,纵坐标
public
boolean
onSegment
(
Double
[]
pi
,
Double
[]
pj
,
Double
[]
Q
)
{
return
(
Q
[
0
]
-
pi
[
0
])
*
(
pj
[
1
]
-
pi
[
1
])
==
(
pj
[
0
]
-
pi
[
0
])
*
(
Q
[
1
]
-
pi
[
1
])
&&
Math
.
min
(
pi
[
0
],
pj
[
0
])
<=
Q
[
0
]
&&
Q
[
0
]
<=
Math
.
max
(
pi
[
0
],
pj
[
0
])
&&
Math
.
min
(
pi
[
1
],
pj
[
1
])
<=
Q
[
1
]
&&
Q
[
1
]
<=
Math
.
max
(
pi
[
1
],
pj
[
1
]);
}
//每一次对比都有保证线段的更新,不能是上一次
public
Double
[]
intersection
(
Double
[]
start1
,
Double
[]
end1
,
Double
[]
start2
,
Double
[]
end2
)
{
ans
=
new
Double
[
0
];
//线段1的开始,线段1的结尾
//线段2的开始,线段2的结尾
Double
x1
=
start1
[
0
],
y1
=
start1
[
1
];
Double
x2
=
end1
[
0
],
y2
=
end1
[
1
];
Double
x3
=
start2
[
0
],
y3
=
start2
[
1
];
Double
x4
=
end2
[
0
],
y4
=
end2
[
1
];
// 判断 (x1, y1)~(x2, y2) 和 (x3, y3)~(x4, y4) 是否平行
if
((
y4
-
y3
)
*
(
x2
-
x1
)
==
(
y2
-
y1
)
*
(
x4
-
x3
))
{
// 若平行,则判断 (x3, y3) 是否在「直线」(x1, y1)~(x2, y2) 上
if
((
y2
-
y1
)
*
(
x3
-
x1
)
==
(
y3
-
y1
)
*
(
x2
-
x1
))
{
// 判断 (x3, y3) 是否在「线段」(x1, y1)~(x2, y2) 上
if
(
inside
(
x1
,
y1
,
x2
,
y2
,
x3
,
y3
))
{
update
(
x3
,
y3
);
}
// 判断 (x4, y4) 是否在「线段」(x1, y1)~(x2, y2) 上
if
(
inside
(
x1
,
y1
,
x2
,
y2
,
x4
,
y4
))
{
update
(
x4
,
y4
);
}
// 判断 (x1, y1) 是否在「线段」(x3, y3)~(x4, y4) 上
if
(
inside
(
x3
,
y3
,
x4
,
y4
,
x1
,
y1
))
{
update
(
x1
,
y1
);
}
// 判断 (x2, y2) 是否在「线段」(x3, y3)~(x4, y4) 上
if
(
inside
(
x3
,
y3
,
x4
,
y4
,
x2
,
y2
))
{
update
(
x2
,
y2
);
}
}
// 在平行时,其余的所有情况都不会有交点
}
else
{
// 联立方程得到 t1 和 t2 的值
double
t1
=
(
double
)
(
x3
*
(
y4
-
y3
)
+
y1
*
(
x4
-
x3
)
-
y3
*
(
x4
-
x3
)
-
x1
*
(
y4
-
y3
))
/
((
x2
-
x1
)
*
(
y4
-
y3
)
-
(
x4
-
x3
)
*
(
y2
-
y1
));
double
t2
=
(
double
)
(
x1
*
(
y2
-
y1
)
+
y3
*
(
x2
-
x1
)
-
y1
*
(
x2
-
x1
)
-
x3
*
(
y2
-
y1
))
/
((
x4
-
x3
)
*
(
y2
-
y1
)
-
(
x2
-
x1
)
*
(
y4
-
y3
));
// 判断 t1 和 t2 是否均在 [0, 1] 之间
if
(
t1
>=
0.0
&&
t1
<=
1.0
&&
t2
>=
0.0
&&
t2
<=
1.0
)
{
ans
=
new
Double
[]{
x1
+
t1
*
(
x2
-
x1
),
y1
+
t1
*
(
y2
-
y1
)};
}
}
return
ans
;
}
// 判断 (xk, yk) 是否在「线段」(x1, y1)~(x2, y2) 上
// 这里的前提是 (xk, yk) 一定在「直线」(x1, y1)~(x2, y2) 上
public
boolean
inside
(
Double
x1
,
Double
y1
,
Double
x2
,
Double
y2
,
Double
xk
,
Double
yk
)
{
// 若与 x 轴平行,只需要判断 x 的部分
// 若与 y 轴平行,只需要判断 y 的部分
// 若为普通线段,则都要判断
return
(
x1
==
x2
||
(
Math
.
min
(
x1
,
x2
)
<=
xk
&&
xk
<=
Math
.
max
(
x1
,
x2
)))
&&
(
y1
==
y2
||
(
Math
.
min
(
y1
,
y2
)
<=
yk
&&
yk
<=
Math
.
max
(
y1
,
y2
)));
}
public
void
update
(
double
xk
,
double
yk
)
{
// 将一个交点与当前 ans 中的结果进行比较
// 若更优则替换
if
(
ans
.
length
==
0
||
xk
<
ans
[
0
]
||
(
xk
==
ans
[
0
]
&&
yk
<
ans
[
1
]))
{
ans
=
new
Double
[]{
xk
,
yk
};
}
}
}
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment