图形搜索支持更多可选项

This commit is contained in:
kercylan98 2023-06-17 19:59:33 +08:00
parent 18b8729a94
commit 3a999a6eb3
3 changed files with 67 additions and 7 deletions

View File

@ -49,6 +49,11 @@ func (slf Shape[V]) String() string {
// 可通过可选项对搜索结果进行过滤 // 可通过可选项对搜索结果进行过滤
func (slf Shape[V]) ShapeSearch(options ...ShapeSearchOption) (result []Shape[V]) { func (slf Shape[V]) ShapeSearch(options ...ShapeSearchOption) (result []Shape[V]) {
opt := &shapeSearchOptions{upperLimit: math.MaxInt} opt := &shapeSearchOptions{upperLimit: math.MaxInt}
opt.directionCountUpper = map[Direction]int{}
for _, d := range Directions {
opt.directionCountUpper[d] = math.MaxInt
}
for _, option := range options { for _, option := range options {
option(opt) option(opt)
} }
@ -123,6 +128,7 @@ func (slf Shape[V]) getAllGraphicComposition(opt *shapeSearchOptions) (result []
var next = -1 var next = -1
var directionPoint = point var directionPoint = point
var links = Shape[V]{point} var links = Shape[V]{point}
var directionCount = map[Direction]int{}
for { for {
var direction Direction var direction Direction
next, direction = slice.NextLoop(Directions, next) next, direction = slice.NextLoop(Directions, next)
@ -135,18 +141,36 @@ func (slf Shape[V]) getAllGraphicComposition(opt *shapeSearchOptions) (result []
break break
} }
links = append(links, directionPoint) links = append(links, directionPoint)
directionCount[direction]++
pos := directionPoint.GetPos(areaWidth) pos := directionPoint.GetPos(areaWidth)
if _, exist := records[pos]; !exist { if _, exist := records[pos]; !exist {
result = append(result, Shape[V]{directionPoint}) result = append(result, Shape[V]{directionPoint})
records[pos] = struct{}{} records[pos] = struct{}{}
} }
} }
if direction == DirectionRight { if direction == DirectionRight {
break break
} }
directionPoint = point directionPoint = point
} }
result = append(result, links)
match := true
for _, direction := range Directions {
c := directionCount[direction]
if c < opt.directionCountLower[direction] || c > opt.directionCountUpper[direction] {
match = false
break
}
}
if match && opt.directionCount > 0 && len(directionCount) != opt.directionCount {
match = false
}
if match {
result = append(result, links)
}
} }
return result return result

View File

@ -1,15 +1,45 @@
package geometry package geometry
type shapeSearchOptions struct { type shapeSearchOptions struct {
lowerLimit int lowerLimit int
upperLimit int upperLimit int
sort int sort int
deduplication bool deduplication bool
directionCountLower map[Direction]int
directionCountUpper map[Direction]int
directionCount int
} }
// ShapeSearchOption 图形搜索可选项,用于 Shape.ShapeSearch 搜索支持 // ShapeSearchOption 图形搜索可选项,用于 Shape.ShapeSearch 搜索支持
type ShapeSearchOption func(options *shapeSearchOptions) type ShapeSearchOption func(options *shapeSearchOptions)
// WithShapeSearchDirectionCountLowerLimit 通过限制特定方向数量下限的方式搜索
func WithShapeSearchDirectionCountLowerLimit(direction Direction, count int) ShapeSearchOption {
return func(options *shapeSearchOptions) {
if options.directionCountLower == nil {
options.directionCountLower = map[Direction]int{}
}
options.directionCountLower[direction] = count
}
}
// WithShapeSearchDirectionCount 通过限制方向数量的方式搜索
func WithShapeSearchDirectionCount(count int) ShapeSearchOption {
return func(options *shapeSearchOptions) {
if options.directionCountLower == nil {
options.directionCountLower = map[Direction]int{}
}
options.directionCount = count
}
}
// WithShapeSearchDirectionCountUpperLimit 通过限制特定方向数量上限的方式搜索
func WithShapeSearchDirectionCountUpperLimit(direction Direction, count int) ShapeSearchOption {
return func(options *shapeSearchOptions) {
options.directionCountUpper[direction] = count
}
}
// WithShapeSearchDeduplication 通过去重的方式进行搜索 // WithShapeSearchDeduplication 通过去重的方式进行搜索
// - 去重方式中每个点仅会被使用一次 // - 去重方式中每个点仅会被使用一次
func WithShapeSearchDeduplication() ShapeSearchOption { func WithShapeSearchDeduplication() ShapeSearchOption {

View File

@ -14,12 +14,18 @@ func TestShape_Search(t *testing.T) {
shape = append(shape, geometry.NewPoint(1, 2)) shape = append(shape, geometry.NewPoint(1, 2))
shape = append(shape, geometry.NewPoint(2, 2)) shape = append(shape, geometry.NewPoint(2, 2))
fmt.Println("形状:")
fmt.Println(shape) fmt.Println(shape)
shapes := shape.ShapeSearch(geometry.WithShapeSearchAsc(), geometry.WithShapeSearchDeduplication()) shapes := shape.ShapeSearch(
geometry.WithShapeSearchDesc(),
geometry.WithShapeSearchDeduplication(),
geometry.WithShapeSearchPointCountLowerLimit(3),
geometry.WithShapeSearchDirectionCount(1),
)
for _, shape := range shapes { for _, shape := range shapes {
fmt.Println("图形", shape.Points()) fmt.Println("搜索", shape.Points())
fmt.Println(shape) fmt.Println(shape)
} }
} }