TA的每日心情 | 开心 2021-3-12 23:18 |
---|
签到天数: 2 天 [LV.1]初来乍到
|
如何判定一个点P是否存在于指定的三角形ABC内,这肯定是一个简单的问题,本文仅用一个图形界面程序展示了该问题。
在此处使用一种常见且简便的方法:如果三角形PAB,PAC和PBC的面积之和与三角形ABC的面积相等,即可判定点P在三角形ABC内(包括在三条边上)。
可知,该方法的关键在于如何计算三角形的面积。幸运地是,当知道三角形顶点(A,B和C)的坐标((Ax, Ay),(Bx, By)和(Cx, Cy))之后,即可计算出其面积:
S
=
|(Ax * By + Bx * Cy + Cx * Zy - Ay * Bx - By * Cx - Cy * Ax) /
2|
关键的代码如下,
//
由给定的三个顶点的坐标,计算三角形面积。
//
Point(java.awt.Point)代表点的坐标。
private
static
double
triangleArea(Point pos1, Point pos2, Point pos3) {
double
result
=
Math.abs((pos1.x
*
pos2.y
+
pos2.x
*
pos3.y
+
pos3.x
*
pos1.y
-
pos2.x
*
pos1.y
-
pos3.x
*
pos2.y
-
pos1.x
*
pos3.y)
/
2.0D
);
return
result;
}
//
判断点pos是否在指定的三角形内。
private
static
boolean
inTriangle(Point pos, Point posA, Point posB,
Point posC) {
double
triangleArea
=
triangleArea(posA, posB, posC);
double
area
=
triangleArea(pos, posA, posB);
area
+=
triangleArea(pos, posA, posC);
area
+=
triangleArea(pos, posB, posC);
double
epsilon
=
0.0001
;
//
由于浮点数的计算存在着误差,故指定一个足够小的数,用于判定两个面积是否(近似)相等。
if
(Math.abs(triangleArea
-
area)
<
epsilon) {
return
true
;
}
return
false
;
}
执行该应用程序,用鼠标在其中点击三次,即可绘制一个三角形,如下组图所示:

然后仅需移动鼠标,就会出现一个空心圆圈。如果圆圈的中心在三角内(包含在三条边上),则圆圈显示为红色;否则,显示为蓝色。如下组图所示:

完整代码如下:
public
class
CanvasPanel
extends
JPanel {
private
static
final
long
serialVersionUID
=
-
6665936180725885346L
;
private
Point firstPoint
=
null
;
private
Point secondPoint
=
null
;
private
Point thirdPoint
=
null
;
public
CanvasPanel() {
setBackground(Color.WHITE);
addMouseListener(mouseAdapter);
addMouseMotionListener(mouseAdapter);
}
public
void
paintComponent(Graphics g) {
super
.paintComponent(g);
drawTriangel(g);
}
private
void
drawTriangel(Graphics g) {
if
(firstPoint
!=
null
&&
secondPoint
!=
null
) {
g.drawLine(firstPoint.x, firstPoint.y, secondPoint.x, secondPoint.y);
if
(thirdPoint
!=
null
) {
g.drawLine(firstPoint.x, firstPoint.y, thirdPoint.x, thirdPoint.y);
g.drawLine(secondPoint.x, secondPoint.y, thirdPoint.x, thirdPoint.y);
}
}
}
private
static
boolean
inTriangle(Point pos, Point posA, Point posB,
Point posC) {
double
triangeArea
=
triangleArea(posA, posB, posC);
double
area
=
triangleArea(pos, posA, posB);
area
+=
triangleArea(pos, posA, posC);
area
+=
triangleArea(pos, posB, posC);
double
epsilon
=
0.0001
;
if
(Math.abs(triangeArea
-
area)
<
epsilon) {
return
true
;
}
return
false
;
}
private
static
double
triangleArea(Point pos1, Point pos2, Point pos3) {
double
result
=
Math.abs((pos1.x
*
pos2.y
+
pos2.x
*
pos3.y
+
pos3.x
*
pos1.y
-
pos2.x
*
pos1.y
-
pos3.x
*
pos2.y
-
pos1.x
*
pos3.y)
/
2.0D
);
return
result;
}
private
MouseInputAdapter mouseAdapter
=
new
MouseInputAdapter() {
public
void
mouseReleased(MouseEvent e) {
Point pos
=
e.getPoint();
if
(firstPoint
==
null
) {
firstPoint
=
pos;
}
else
if
(secondPoint
==
null
) {
secondPoint
=
pos;
Graphics g
=
CanvasPanel.
this
.getGraphics();
CanvasPanel.
this
.paintComponent(g);
g.drawLine(firstPoint.x, firstPoint.y, secondPoint.x, secondPoint.y);
}
else
if
(thirdPoint
==
null
) {
thirdPoint
=
pos;
Graphics g
=
CanvasPanel.
this
.getGraphics();
CanvasPanel.
this
.paintComponent(g);
g.drawLine(firstPoint.x, firstPoint.y, secondPoint.x, secondPoint.y);
g.drawLine(firstPoint.x, firstPoint.y, thirdPoint.x, thirdPoint.y);
g.drawLine(secondPoint.x, secondPoint.y, thirdPoint.x, thirdPoint.y);
}
}
public
void
mouseMoved(MouseEvent e) {
Point pos
=
e.getPoint();
Graphics2D g2
=
(Graphics2D) CanvasPanel.
this
.getGraphics();
CanvasPanel.
this
.paintComponent(g2);
if
(firstPoint
!=
null
&&
secondPoint
==
null
) {
g2.drawLine(firstPoint.x, firstPoint.y, pos.x, pos.y);
}
else
if
(firstPoint
!=
null
&&
secondPoint
!=
null
&&
thirdPoint
==
null
) {
g2.drawLine(firstPoint.x, firstPoint.y, pos.x, pos.y);
g2.drawLine(secondPoint.x, secondPoint.y, pos.x, pos.y);
}
else
if
(firstPoint
!=
null
&&
secondPoint
!=
null
&&
thirdPoint
!=
null
) {
if
(inTriangle(pos, firstPoint, secondPoint, thirdPoint)) {
g2.setColor(Color.RED);
}
else
{
g2.setColor(Color.BLUE);
}
int
radius
=
4
;
g2.drawOval(pos.x
-
radius, pos.y
-
radius, radius
*
2
, radius
*
2
);
}
}
};
}
public
class
Triangle
extends
JFrame {
private
static
final
long
serialVersionUID
=
1L
;
private
CanvasPanel mainPanel
=
null
;
public
Triangle() {
setTitle(
"
Triangle
"
);
setSize(
new
Dimension(
300
,
200
));
setResizable(
false
);
init();
Container container
=
getContentPane();
container.add(mainPanel);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(
true
);
}
private
void
init() {
mainPanel
=
new
CanvasPanel();
}
public
static
void
main(String[] args) {
new
Triangle();
}
} |
|