rtss-core/model/link.go

161 lines
3.4 KiB
Go
Raw Normal View History

2024-06-07 18:38:38 +08:00
package model
2024-07-01 19:49:24 +08:00
import (
"fmt"
2024-07-01 19:49:24 +08:00
"io"
"math"
2024-07-01 19:49:24 +08:00
)
2024-06-17 19:45:38 +08:00
type RR = io.Writer
// 轨道
// 默认坐标系为以A端为起点B端为终点的单轴坐标系
2024-06-07 18:38:38 +08:00
type Link interface {
TwoPortsPipeElement
IsEquals(pla *PipeLink, plb *PipeLink) bool
// 获取轨道长度单位毫米mm
GetLength() int64
2024-06-17 19:45:38 +08:00
}
// 轨道连接点(使用的是道岔岔心)然后有三个方向A/B/C还是使用PipePort枚举但表示的含义是方向而不是道岔的三个端口
2024-06-17 19:45:38 +08:00
type LinkNode interface {
Turnout() Turnout
ThreePortsPipeElement
2024-06-17 19:45:38 +08:00
}
type LinkDirection int
const (
LinkDirectionB2A LinkDirection = -1
LinkDirectionA2B LinkDirection = 1
)
// link位置
type LinkPosition struct {
link Link
pos int64
}
func NewLinkPosition(link Link, pos int64) *LinkPosition {
return &LinkPosition{
link: link,
pos: pos,
}
}
func (lp *LinkPosition) Link() Link {
return lp.link
}
func (lp *LinkPosition) Position() int64 {
return lp.pos
}
func (lp *LinkPosition) IsIn(linkRange LinkRange) bool {
return lp.link.Uid() == linkRange.link.Uid() && lp.IsInRange(linkRange.start, linkRange.end)
}
func (lp *LinkPosition) IsInRange(a int64, b int64) bool {
start := int64(math.Min(float64(a), float64(b)))
end := int64(math.Max(float64(a), float64(b)))
return lp.pos >= start && lp.pos <= end
}
// 移动位置
func (lp *LinkPosition) Move(len uint32, direction LinkDirection) (overflow bool) {
lp.pos += int64(len) * int64(direction)
if lp.pos > lp.link.GetLength() || lp.pos < 0 {
overflow = true
}
return
}
// link范围
type LinkRange struct {
link Link
start int64
end int64
}
// 构造link范围
// link: 轨道 不能为nil
// a: 起始位置b: 结束位置单位毫米mma和b不能相等
func NewLinkRange(link Link, a int64, b int64) *LinkRange {
if link == nil {
panic("构造LinkRange错误: link不能为空")
}
if a == b {
panic("构造LinkRange错误: a和b不能相等")
}
start := int64(math.Min(float64(a), float64(b)))
end := int64(math.Max(float64(a), float64(b)))
return &LinkRange{
link: link,
start: start,
end: end,
}
}
2024-06-24 18:20:11 +08:00
var _ Link = (*LinkImpl)(nil)
var _ LinkNode = (*LinkNodeImpl)(nil)
2024-06-17 19:45:38 +08:00
type LinkImpl struct {
*TwoPortsPipeElementImpl
len int64
2024-06-17 19:45:38 +08:00
}
type LinkNodeImpl struct {
2024-06-27 19:59:13 +08:00
turnout Turnout
*ThreePortsPipeElementImpl
2024-06-17 19:45:38 +08:00
}
func NewLink(pla *PipeLink, plb *PipeLink) *LinkImpl {
uid := buildLinkUid(pla, plb)
2024-06-17 19:45:38 +08:00
return &LinkImpl{
TwoPortsPipeElementImpl: &TwoPortsPipeElementImpl{
2024-06-27 19:59:13 +08:00
uid: uid,
},
2024-06-17 19:45:38 +08:00
}
}
2024-07-01 19:49:24 +08:00
func NewLinkNode(turnout Turnout) *LinkNodeImpl {
if turnout == nil {
panic("构造LinkNode错误: 道岔不能为空")
}
2024-06-17 19:45:38 +08:00
return &LinkNodeImpl{
turnout: turnout,
ThreePortsPipeElementImpl: &ThreePortsPipeElementImpl{
2024-06-27 19:59:13 +08:00
uid: turnout.Uid(),
},
2024-06-17 19:45:38 +08:00
}
}
func (l *LinkImpl) IsEquals(pla *PipeLink, plb *PipeLink) bool {
return l.uid == buildLinkUid(pla, plb) || l.uid == buildLinkUid(plb, pla)
2024-07-01 19:49:24 +08:00
}
func (l *LinkImpl) GetLength() int64 {
return l.len
}
func (l *LinkImpl) SetLength(len int64) {
l.len = len
}
2024-06-17 19:45:38 +08:00
func (n *LinkNodeImpl) Turnout() Turnout {
return n.turnout
}
func buildLinkUid(pla *PipeLink, plb *PipeLink) string {
if pla == nil && plb == nil {
panic("构造link Uid错误: pla和plb不能同时为空")
2024-06-17 19:45:38 +08:00
}
if pla == nil {
return fmt.Sprintf("end->%s(%s)", plb.Pipe.Uid(), plb.Port)
2024-06-17 19:45:38 +08:00
}
if plb == nil {
return fmt.Sprintf("%s(%s)->end", pla.Pipe.Uid(), pla.Port)
2024-06-17 19:45:38 +08:00
}
return fmt.Sprintf("%s(%s)->%s(%s)", pla.Pipe.Uid(), pla.Port, plb.Pipe.Uid(), plb.Port)
2024-06-07 18:38:38 +08:00
}