From 319bad13bd31500cc0e3206ed5eed205c3442932 Mon Sep 17 00:00:00 2001 From: kercylan <61743331+kercylan98@users.noreply.github.com> Date: Sun, 4 Jun 2023 15:47:38 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=9C=80=E4=BD=8E=E9=95=BF?= =?UTF-8?q?=E5=BA=A6=E4=B8=BA3=E7=9A=84=E7=9B=B4=E7=BA=BF=E6=90=9C?= =?UTF-8?q?=E7=B4=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- utils/g2d/matrix/match3_test.go | 10 ++++ utils/g2d/shape.go | 97 +++++++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+) diff --git a/utils/g2d/matrix/match3_test.go b/utils/g2d/matrix/match3_test.go index d94c4e7..dd54476 100644 --- a/utils/g2d/matrix/match3_test.go +++ b/utils/g2d/matrix/match3_test.go @@ -106,4 +106,14 @@ func TestMatch3(t *testing.T) { fmt.Println() } fmt.Println("耗时", time.Since(now)) + + now = time.Now() + for _, rect := range g2d.SearchNotRepeatStraightLine(3, xys...) { + fmt.Print("找到直线:") + for _, points := range rect { + fmt.Print(fmt.Sprintf("{%d, %d}", points[0], points[1])) + } + fmt.Println() + } + fmt.Println("耗时", time.Since(now)) } diff --git a/utils/g2d/shape.go b/utils/g2d/shape.go index df9fad4..5f55a88 100644 --- a/utils/g2d/shape.go +++ b/utils/g2d/shape.go @@ -221,6 +221,103 @@ func SearchNotRepeatCross(xys ...[2]int) (result [][][2]int) { return notRepeat } +// SearchNotRepeatStraightLine 在一组二维坐标中从大到小搜索不重复的直线 +// - 最低需要长度为3 +func SearchNotRepeatStraightLine(minLength int, xys ...[2]int) (result [][][2]int) { + if minLength < 3 { + return nil + } + left, _, top, _ := GetShapeCoverageArea(xys...) + rectangleShape := GenerateShape(xys...) + record := map[int]map[int]bool{} + for x := 0; x < len(rectangleShape); x++ { + for y := 0; y < len(rectangleShape[0]); y++ { + record[x] = map[int]bool{} + } + } + + for _, xy := range xys { + var points [][2]int + var find = map[int]bool{} + x, y := PositionArrayToXY(xy) + x = x + (0 - left) + y = y + (0 - top) + // 搜索四个方向 + for sx := x - 1; sx >= 0; sx-- { + if !rectangleShape[sx][y] { + break + } + find[1] = true + points = append(points, [2]int{sx + left, y + top}) + } + if !find[1] { + goto up + } + for sx := x + 1; sx < len(rectangleShape); sx++ { + if !rectangleShape[sx][y] { + break + } + find[2] = true + points = append(points, [2]int{sx + left, y + top}) + } + if !find[2] { + points = nil + } + up: + for sy := y - 1; sy >= 0; sy-- { + if !rectangleShape[x][sy] { + break + } + find[3] = true + points = append(points, [2]int{x + left, sy + top}) + } + if !find[3] { + continue + } + for sy := y + 1; sy < len(rectangleShape[0]); sy++ { + if !rectangleShape[x][sy] { + break + } + find[4] = true + points = append(points, [2]int{x + left, sy + top}) + } + if !find[4] { + continue + } + if len(find) != 2 { + continue + } + result = append(result, append(points, [2]int{x + left, y + top})) + } + + sort.Slice(result, func(i, j int) bool { + return len(result[i]) > len(result[j]) + }) + + var notRepeat [][][2]int + for _, points := range result { + if len(points) < minLength { + continue + } + var match = true + for _, point := range points { + x, y := PositionArrayToXY(point) + x = x + (0 - left) + y = y + (0 - top) + if record[x][y] { + match = false + break + } + record[x][y] = true + } + if match { + notRepeat = append(notRepeat, points) + } + } + + return notRepeat +} + // SearchNotRepeatT 在一组二维坐标中从大到小搜索不重复T型(T)线 func SearchNotRepeatT(minLength int, xys ...[2]int) (result [][][2]int) { if minLength < 4 {