判断一个点是否在三角形内部【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)

	}
}

posted @ 2022-07-16 23:00  Tacey Wong  阅读(86)  评论(0编辑  收藏  举报