判断一个点是否在三角形内部【Golang实现】
【题目】
在二维坐标系中,所有的值都是double类型,那么一个三角形可以由3个点来代表,给定3个点代表的三角形,再给定一个点(x ,y ),判断(x ,y )是否在三角形中。
解决方案
方案一:基于面积
package main
import (
"fmt"
"math"
)
type Point struct {
x float64
y float64
}
type Triangle struct {
p1, p2, p3 Point
}
func (t *Triangle) IsInside(p Point) bool {
area1 := getArea(t.p1, t.p2, p)
area2 := getArea(t.p1, t.p3, p)
area3 := getArea(t.p2, t.p3, p)
areaAll := getArea(t.p1, t.p2, t.p3)
fmt.Println(area1, area2, area3, areaAll)
return areaAll >= (area1 + area2 + area3)
}
// 计算两点的距离
func getSideLength(p1, p2 Point) float64 {
a := math.Abs(p1.x - p2.x)
b := math.Abs(p1.y - p2.y)
return math.Sqrt(a*a + b*b)
}
// 根据三点坐标计算三角形面积(海伦公式)
func getArea(p1, p2, p3 Point) float64 {
side1Len := getSideLength(p1, p2)
side2Len := getSideLength(p1, p3)
side3Len := getSideLength(p2, p3)
p := (side1Len + side2Len + side3Len) / 2
return math.Sqrt((p - side1Len) * (p - side2Len) * (p - side3Len) * p)
}
func main() {
t := Triangle{Point{0, 100}, Point{0, 0}, Point{100, 0}}
p := Point{2, 2}
if t.IsInside(p) {
fmt.Println(p, "在", t)
} else {
fmt.Println(p, "不在", t)
}
}
方案二:基于矢量叉乘运算
package main
import (
"fmt"
)
type Point struct {
x float64
y float64
}
type Triangle struct {
p1, p2, p3 Point
}
// 最好切换成复数计算
func crossProduct(x1, y1, x2, y2 float64) float64 {
// 向量(x 1,y 1)叉乘向量(x 2,y 2)
return x1*y2 - y1*x2
}
func (t *Triangle) IsInside(p Point) bool {
// 调整顺序
if crossProduct(t.p3.x-t.p1.x, t.p3.y-t.p1.y,
t.p2.x-t.p1.x, t.p2.y-t.p1.y) >= 0 {
t.p2.x, t.p2.y, t.p3.x, t.p3.y = t.p3.x, t.p3.y, t.p2.x, t.p2.y
}
// switch
if crossProduct(t.p2.x-t.p1.x, t.p2.y-t.p1.y,
p.x-t.p1.x, p.y-t.p1.y) < 0 ||
crossProduct(t.p3.x-t.p2.x, t.p3.y-t.p2.y,
p.x-t.p2.x-p.x, p.y-t.p2.y) < 0 ||
crossProduct(t.p1.x-t.p3.x, t.p1.y-t.p3.y,
p.x-t.p3.x, p.y-t.p3.y) < 0 {
return false
}
return true
}
func main() {
rect := Triangle{Point{0, 100}, Point{0, 0}, Point{100, 0}}
p := Point{1, 200}
if rect.IsInside(p) {
fmt.Println(p, "在", rect)
} else {
fmt.Println(p, "不在", rect)
}
}
还真有人点开啊🤣随意随意😂