您的位置:首页 > 其它

判断两三角形是否相交

2015-07-27 11:01 344 查看
1,原理:在上篇文章中我们可以判断点是否在三角形内。这张判断两三角形是否相交,只需要判断三角形A的三个顶点不在三角形B内,三角形B的三个顶点不在三角形A则满足两三角形相离,并且判断三角形A的三条边与三角形B 都不想交

代码如下:

// test project main.go
package main

import (
"fmt"
)

//坐标
type victor struct {
X float32
Y float32
}

func main() {
//测试点
pA1 := &victor{0, 0}
pA2 := &victor{2, 0}
pA3 := &victor{2, 2}
pB1 := &victor{1.5, -1}
pB2 := &victor{0, 1}
pB3 := &victor{1.5, 2}
IsCorssTriangle(pA1, pA2, pA3, pB1, pB2, pB3)

}

//判线段是否在三角形内
func IsCorssTriangle(pA1 *victor, pA2 *victor, pA3 *victor, pB1 *victor, pB2 *victor, pB3 *victor) bool {
//比例系数(p1.X - p2.X) / (p1.Y - p2.Y)
//C p1.Y-((p1.X - p2.X) / (p1.Y - p2.Y))*p1.X
//IsTriangle判断是否是三角形
if !IsTriangle(pA1, pA2, pA3) {
fmt.Println("该三点不能组成三角形")
return false
}
//IsTriangle判断是否是三角形
if !IsTriangle(pB1, pB2, pB3) {
fmt.Println("该三点不能组成三角形")
return false
}
//A三角形三点如果全部在B的外面 并且B的三点全部在A的外面 满足这个条件三角形必定不相交 true 是相交 false 不相交
if IsInTriangle(pA1, pA2, pA3, pB1) && IsInTriangle(pA1, pA2, pA3, pB2) && IsInTriangle(pA1, pA2, pA3, pB3) && IsInTriangle(pB1, pB2, pB3, pA1) && IsInTriangle(pB1, pB2, pB3, pA3) && IsInTriangle(pB1, pB2, pB3, pA2) {
fmt.Println("相交了哦")
return true
}
//A三角的三条直线是否和B三角形相交
if IsCorssDirec(pA1, pA2, pB1, pB2) || IsCorssDirec(pA1, pA2, pB1, pB3) || IsCorssDirec(pA1, pA2, pB2, pB2) {
fmt.Println("相交了哦")
return true
}
if IsCorssDirec(pA1, pA3, pB1, pB2) || IsCorssDirec(pA1, pA3, pB1, pB3) || IsCorssDirec(pA1, pA3, pB2, pB2) {
fmt.Println("相交了哦")
return true
}
if IsCorssDirec(pA3, pA2, pB1, pB2) || IsCorssDirec(pA3, pA2, pB1, pB3) || IsCorssDirec(pA3, pA2, pB2, pB2) {
fmt.Println("相交了哦")
return true
}
fmt.Println("两三角形不想交")
return false
}

//判断两条直线是否相交 true 是相交 false 不相交
func IsCorssDirec(pA1 *victor, pA2 *victor, pB1 *victor, pB2 *victor) bool {
if GetMinger(pA1.X, pA2.X) > GetBigger(pB1.X, pB2.X) {
return false
}
if GetMinger(pA1.Y, pA2.Y) > GetBigger(pB1.Y, pB2.Y) {
return false
}
if GetBigger(pA1.Y, pA2.Y) < GetMinger(pB1.Y, pB2.Y) {
return false
}
if GetBigger(pA1.X, pA2.X) < GetMinger(pB1.X, pB2.X) {
return false
}
if mult(pB1, pA2, pA1)*mult(pA2, pB2, pA1) < 0 {
return false
}
if mult(pA1, pB2, pB1)*mult(pB2, pA2, pB1) < 0 {
return false
}
return true
}

//叉积
func mult(a *victor, b *victor, c *victor) float32 {
return (a.X-c.X)*(b.Y-c.Y) - (b.X-c.X)*(a.Y-c.Y)
}

//获取大数字
func GetBigger(a, b float32) float32 {
if a > b {
return a
} else {
return b
}
}

//获取大数字
func GetMinger(a, b float32) float32 {
if a > b {
return b
} else {
return a
}
}

//判断点是否在三角形内
func IsInTriangle(p1 *victor, p2 *victor, p3 *victor, p *victor) bool {
//IsTriangle判断是否是三角形
if !IsTriangle(p1, p2, p3) {
fmt.Println("该三点不能组成三角形")
return false
}
//判断点是否在三角形的三条边同侧
if IsSameDirec(p1, p2, p3, p) && IsSameDirec(p1, p3, p2, p) && IsSameDirec(p3, p2, p1, p) {
fmt.Println("点在三角形里面")
return true
} else {
fmt.Println("在三角形外面")
return false
}

}

//判断是否是三角形
//p1,p2,p3分别为三个顶点坐标
func IsTriangle(p1 *victor, p2 *victor, p3 *victor) bool {
//是否三点X坐标相同
if p1.X == p2.X && p1.X == p3.X {
return false
}
//是否三点Y坐标相同
if p1.Y == p2.Y && p1.Y == p3.Y {
return false
}
return true
}

//求第三点与另外两点直线是否同侧
//p1,p2 为三角形的两顶点
//p为测试点
func IsSameDirec(p1 *victor, p2 *victor, p3 *victor, p *victor) bool {
//比例系数(p1.X - p2.X) / (p1.Y - p2.Y)
//C p1.Y-((p1.X - p2.X) / (p1.Y - p2.Y))*p1.X
var tag bool

//如果 p1.X=p2.X则此时与Y轴平行,只需要比较X
if p1.X == p2.X {
if (p3.X >= p1.X && p.X >= p1.X) || (p3.X < p1.X && p.X < p1.X) {
return true
} else {
return false
}
} else {
//如果P3在直线上面就为true
if p3.Y >= (p1.Y-p2.Y)/(p1.X-p2.X)*p3.X+p1.Y-((p1.Y-p2.Y)/(p1.X-p2.X))*p1.X {
tag = true
} else {
tag = false
}
if tag {
if p.Y >= (p1.Y-p2.Y)/(p1.X-p2.X)*p.X+p1.Y-((p1.Y-p2.Y)/(p1.X-p2.X))*p1.X {
return true
}
} else {
if p.Y < (p1.Y-p2.Y)/(p1.X-p2.X)*p.X+p1.Y-((p1.Y-p2.Y)/(p1.X-p2.X))*p1.X {
return true
}
}
return false
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: