版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
今天下午在图书馆待了一下午的时间做出来这个作业题,首先来看以下这个题目
题目
这个题目标着三颗星,看起来很难,做起来有点难。
难点
我个人认为有以下几个难点:
- 判定一个点在三角形内是最难的
- 其实是一个三角形在另一个三角形内
- 其次是一个三角形和一个三角形重叠。
解决方案
- 判定一个点在三角形内。
这个判定,我在网上搜索了很久并理解了很久才明白(hmmm,可能是我天资愚钝吧,好长时间才弄明白)- 下图中的p 点在三角形p1p2p3中,我们可以看到向量p1->p2, 或者 p2->p3, 或者p3->p1,按照这个方向行走的话,这个p点始终在向量的右侧, 这样判定三次(三条边)就可以完成
- 但是在程序中我们就不能分辨出左右来,然后我们就判定p和向量的另外一点在同一侧就好了。例如向量p1->p2, 可见p和p3都在向量p1->p2的同侧,这样判定三次就可以判定出一个点在三角形内。
解决方案的代码如下
/** If p is in this triangle, return true; */
public boolean contains(MyPoint p) {
// The first edge
boolean bool1 = sameSide(p1, p2, p, p3);
boolean bool2 = sameSide(p1, p3, p, p2);
boolean bool3 = sameSide(p2, p3, p, p1);
if (bool1 && bool2 && bool3)
return true;
else
return false;
}
/** If p and p3 is on the same side, return true */
public boolean sameSide(MyPoint p1, MyPoint p2, MyPoint p, MyPoint p3) {
// Save the the product of the two vector product
double a = vectorProduct(p1, p2, p3) * vectorProduct(p1, p2, p);
if (a > 0)
return true;
else
return false;
}
/** Return the vector product for p->p2 and p2->p1 */
public double vectorProduct(MyPoint p1, MyPoint p2, MyPoint p) {
double x1 = p2.getX() - p.getX();
double y1 = p2.getX() - p.getX();
double Xab = p1.getX() - p2.getX();
double Yab = p1.getX() - p2.getY();
double vectorProduct = Xab * y1 - x1 * Yab;
// double vectorProduct = x1 * Xab + y1 * Yab;
return vectorProduct;
}
-
一个三角形在另一个三角形内
我们判定成功了一个点在一个三角形内,那么我们就比较容易判定一个三角形在另一个三角形内了,我们只需要一个三角形中的三个点全部在另一个三角形中就好了
代码如下
/** If t contains this triangle or this on the contrary, return true */
public boolean contains(Triangle2D t) {
// thisTriangle contains t
boolean b1 = contains(t.getP1()) && contains(t.getP2()) && contains(t.getP3());
boolean b2 = t.contains(p1) && t.contains(p2) && t.contains(p3);
return b1 ^ b2;
/*
* if(b1 && b2) { // If t contains this triangle and this triangle contains t,
* the two triangles are same }
*/
}
- 判定一个三角形和另一个三角形重叠
- 该怎么判定呢?三个点都在三角形外?显然不符合实际。一个点在三角形内也可以重叠啊
- 判定的方法是,只要有任意一条边与另外三遍有相交就好。。
代码如下
/**
* If this triangle overlaps t, return true Solution: any line has intersections
* with the other triangle, then the two triangle overlap
*/
public boolean overlaps(Triangle2D t) {
// p1_p2 of triangle t and 3 edges in this
boolean b1 = lineIntersection(p1, p2, t.getP1(), t.getP2());
boolean b2 = lineIntersection(p2, p3, t.getP1(), t.getP2());
boolean b3 = lineIntersection(p1, p3, t.getP1(), t.getP2());
// p1_p3 of triangle t and 3 edges in this
boolean b4 = lineIntersection(p1, p2, t.getP1(), t.getP3());
boolean b5 = lineIntersection(p2, p3, t.getP1(), t.getP3());
boolean b6 = lineIntersection(p1, p3, t.getP1(), t.getP3());
// p2_p3 of triangle t and 3 edges in this
boolean b7 = lineIntersection(p1, p2, t.getP2(), t.getP3());
boolean b8 = lineIntersection(p2, p3, t.getP2(), t.getP3());
boolean b9 = lineIntersection(p1, p3, t.getP2(), t.getP3());
// return b1 || b2 || b3 || b4 || b5 || b6 || b7 || b8 || b9;
return b1 && b2 && b3 && b4 && b5 && b6 && b7 && b8 && b9;
}
/** If two line intersect with each other, return true */
public boolean lineIntersection(MyPoint p1, MyPoint p2, MyPoint p3, MyPoint p4) {
double a = p1.getY() - p2.getY();
double b = p2.getX() - p1.getX();
double c = p3.getY() - p4.getY();
double d = p4.getX() - p3.getX();
double denominator = a * d - b * c;
if (denominator != 0) {
return true;
} else {
return false;
}
}
完整的测试代码如下
package answer.homework;
/**
* @author Master_Joe
*
*/
public class Answer10_12 {
/** Main method, in other word, this is testTriangle2D */
public static void main(String[] args) {
Triangle2D t1 = new Triangle2D(new MyPoint(2.5, 2), new MyPoint(4.2, 3), new MyPoint(5, 3.5));
System.out.println("The area of the triangle t1 " + t1.toString() + " is " + t1.getArea()
+ ", and its perimeter is " + t1.getPerimeter());
System.out.println("t1.contains(3, 3) is " + t1.contains(new MyPoint(3, 3)));
System.out.println("t1.contains(new Triangle2D(new MyPoint(2.9, 2), new MyPoint(4, 1), MyPoint(1, 3.4))) is "
+ t1.contains(new Triangle2D(new MyPoint(2.9, 2), new MyPoint(4, 1), new MyPoint(1, 3.4))));
System.out
.println("t1.overlaps(new Triangle2D(new MyPoint(2, 5.5), new MyPoint(4, -3), new MyPoint(2, 6.5))) is "
+ t1.overlaps(new Triangle2D(new MyPoint(2, 5.5), new MyPoint(4, -3), new MyPoint(2, 6.5))));
// System.out
// .println("t1.overlaps(new Triangle2D(new MyPoint(2.9, 2), new MyPoint(4, 1), new MyPoint(1, 3.4)))) is "
// + t1.overlaps(new Triangle2D(new MyPoint(2.9, 2), new MyPoint(4, 1), new MyPoint(1, 3.4))));
}
}
class Triangle2D {
private MyPoint p1;
private MyPoint p2;
private MyPoint p3;
public Triangle2D() {
this.p1 = new MyPoint(0, 0);
this.p2 = new MyPoint(1, 1);
this.p3 = new MyPoint(2, 5);
}
public Triangle2D(MyPoint p1, MyPoint p2, MyPoint p3) {
this.p1 = p1;
this.p2 = p2;
this.p3 = p3;
}
public MyPoint getP1() {
return p1;
}
public void setP1(double x, double y) {
p1 = new MyPoint(x, y);
}
public MyPoint getP2() {
return p2;
}
public void setP2(double x, double y) {
p2 = new MyPoint(x, y);
}
public MyPoint getP3() {
return p3;
}
public void setP3(double x, double y) {
p3 = new MyPoint(x, y);
}
public double getPerimeter() {
return p1.distance(p2) + p1.distance(p3) + p2.distance(p3);
}
public double getArea() {
double a = p1.distance(p2);
double b = p1.distance(p3);
double c = p2.distance(p3);
double p = this.getPerimeter() / 2;
return Math.sqrt(p * (p - a) * (p - b) * (p - c));
// return Math.sqrt(this.getPerimeter() / 2 * (this.getPerimeter() / 2 - p1.distance(p2))
// * (this.getPerimeter() / 2 - p1.distance(p3)) * (this.getPerimeter() / 2 - p2.distance(p3)));
}
/** If p is in this triangle, return true; */
public boolean contains(MyPoint p) {
// The first edge
boolean bool1 = sameSide(p1, p2, p, p3);
boolean bool2 = sameSide(p1, p3, p, p2);
boolean bool3 = sameSide(p2, p3, p, p1);
if (bool1 && bool2 && bool3)
return true;
else
return false;
}
/** If t contains this triangle or this on the contrary, return true */
public boolean contains(Triangle2D t) {
// thisTriangle contains t
boolean b1 = contains(t.getP1()) && contains(t.getP2()) && contains(t.getP3());
boolean b2 = t.contains(p1) && t.contains(p2) && t.contains(p3);
return b1 ^ b2;
/**
* if(b1 && b2) { // If t contains this triangle and this triangle contains t,
* the two triangles are same } but maybe it is not right
*/
}
/**
* If this triangle overlaps t, return true Solution: any line has intersections
* with the other triangle, then the two triangle overlap
*/
public boolean overlaps(Triangle2D t) {
// p1_p2 of triangle t and 3 edges in this
boolean b1 = lineIntersection(p1, p2, t.getP1(), t.getP2());
boolean b2 = lineIntersection(p2, p3, t.getP1(), t.getP2());
boolean b3 = lineIntersection(p1, p3, t.getP1(), t.getP2());
// p1_p3 of triangle t and 3 edges in this
boolean b4 = lineIntersection(p1, p2, t.getP1(), t.getP3());
boolean b5 = lineIntersection(p2, p3, t.getP1(), t.getP3());
boolean b6 = lineIntersection(p1, p3, t.getP1(), t.getP3());
// p2_p3 of triangle t and 3 edges in this
boolean b7 = lineIntersection(p1, p2, t.getP2(), t.getP3());
boolean b8 = lineIntersection(p2, p3, t.getP2(), t.getP3());
boolean b9 = lineIntersection(p1, p3, t.getP2(), t.getP3());
// return b1 || b2 || b3 || b4 || b5 || b6 || b7 || b8 || b9;
return b1 && b2 && b3 && b4 && b5 && b6 && b7 && b8 && b9;
}
/** If p and p3 is on the same side, return true */
public boolean sameSide(MyPoint p1, MyPoint p2, MyPoint p, MyPoint p3) {
// Save the the product of the two vector product
double a = vectorProduct(p1, p2, p3) * vectorProduct(p1, p2, p);
if (a > 0)
return true;
else
return false;
}
/** Return the vector product for p->p2 and p2->p1 */
public double vectorProduct(MyPoint p1, MyPoint p2, MyPoint p) {
double x1 = p2.getX() - p.getX();
double y1 = p2.getX() - p.getX();
double Xab = p1.getX() - p2.getX();
double Yab = p1.getX() - p2.getY();
double vectorProduct = Xab * y1 - x1 * Yab;
// double vectorProduct = x1 * Xab + y1 * Yab;
return vectorProduct;
}
/** If two line intersect with each other, return true */
public boolean lineIntersection(MyPoint p1, MyPoint p2, MyPoint p3, MyPoint p4) {
double a = p1.getY() - p2.getY();
double b = p2.getX() - p1.getX();
double c = p3.getY() - p4.getY();
double d = p4.getX() - p3.getX();
double denominator = a * d - b * c;
if (denominator != 0) {
return true;
} else {
return false;
}
}
/** Decide if a point p is on the line p1->p2 */
public boolean onSegment(MyPoint p1, MyPoint p2, MyPoint p) {
double parameter = (p2.getX() - p1.getX()) * (p.getY() - p1.getY())
- (p.getX() - p1.getX()) * (p2.getY() - p1.getY());
if (parameter == 0 && p.getX() <= Math.max(p1.getX(), p2.getX()) && p.getX() >= Math.min(p1.getX(), p2.getX())
&& p.getY() <= Math.max(p1.getY(), p2.getY()) && p.getY() >= Math.min(p1.getY(), p2.getY()))
return true;
else
return false;
}
/** Return the point intersection */
public MyPoint getIntersection(MyPoint p1, MyPoint p2, MyPoint p3, MyPoint p4) {
MyPoint point;
double a = p1.getY() - p2.getY();
double b = p2.getX() - p1.getX();
double c = p3.getY() - p4.getY();
double d = p4.getX() - p3.getX();
double e = (p1.getY() - p2.getY()) * p1.getX() - (p1.getX() - p2.getX()) * p1.getY();
double f = (p3.getY() - p4.getY()) * p3.getX() - (p3.getX() - p4.getX()) * p3.getY();
double denominator = a * d - b * c;
if (denominator != 0) {
double x = (e * d - b * f) / denominator;
double y = (a * f - e * c) / denominator;
point = new MyPoint(x, y);
} else {
point = new MyPoint(-999, -999); // If there is no intersection, return point (-999, -999)
}
return point;
}
@Override
public String toString() {
return "[" + p1.toString() + "," + p2.toString() + ", " + p3.toString() + "]";
}
}
运行结果如下
The area of the triangle t1 [(2.5, 2.0),(4.2, 3.0), (5.0, 3.5)] is 0.02500000000000299, and its perimeter is 5.831182352959913
t1.contains(3, 3) is false
t1.contains(new Triangle2D(new MyPoint(2.9, 2), new MyPoint(4, 1), MyPoint(1, 3.4))) is false
t1.overlaps(new Triangle2D(new MyPoint(2, 5.5), new MyPoint(4, -3), new MyPoint(2, 6.5))) is true
以上如果有错误
以上如果有错误,欢迎联系我改正,非常欢迎大家帮助我,谢谢
我的联系方式为[email protected]