rtss-core/model/link.go
soul-walker 1a610c01ba 调整公里标概念,添加注释说明
完善道岔区段与道岔关系构建检查
添加Link位置和link范围工具类
完善example道岔区段关系构建
2024-07-10 18:09:16 +08:00

161 lines
3.4 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package model
import (
"fmt"
"io"
"math"
)
type RR = io.Writer
// 轨道
// 默认坐标系为以A端为起点B端为终点的单轴坐标系
type Link interface {
TwoPortsPipeElement
IsEquals(pla *PipeLink, plb *PipeLink) bool
// 获取轨道长度单位毫米mm
GetLength() int64
}
// 轨道连接点(使用的是道岔岔心)然后有三个方向A/B/C还是使用PipePort枚举但表示的含义是方向而不是道岔的三个端口
type LinkNode interface {
Turnout() Turnout
ThreePortsPipeElement
}
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,
}
}
var _ Link = (*LinkImpl)(nil)
var _ LinkNode = (*LinkNodeImpl)(nil)
type LinkImpl struct {
*TwoPortsPipeElementImpl
len int64
}
type LinkNodeImpl struct {
turnout Turnout
*ThreePortsPipeElementImpl
}
func NewLink(pla *PipeLink, plb *PipeLink) *LinkImpl {
uid := buildLinkUid(pla, plb)
return &LinkImpl{
TwoPortsPipeElementImpl: &TwoPortsPipeElementImpl{
uid: uid,
},
}
}
func NewLinkNode(turnout Turnout) *LinkNodeImpl {
if turnout == nil {
panic("构造LinkNode错误: 道岔不能为空")
}
return &LinkNodeImpl{
turnout: turnout,
ThreePortsPipeElementImpl: &ThreePortsPipeElementImpl{
uid: turnout.Uid(),
},
}
}
func (l *LinkImpl) IsEquals(pla *PipeLink, plb *PipeLink) bool {
return l.uid == buildLinkUid(pla, plb) || l.uid == buildLinkUid(plb, pla)
}
func (l *LinkImpl) GetLength() int64 {
return l.len
}
func (l *LinkImpl) SetLength(len int64) {
l.len = len
}
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不能同时为空")
}
if pla == nil {
return fmt.Sprintf("end->%s(%s)", plb.Pipe.Uid(), plb.Port)
}
if plb == nil {
return fmt.Sprintf("%s(%s)->end", pla.Pipe.Uid(), pla.Port)
}
return fmt.Sprintf("%s(%s)->%s(%s)", pla.Pipe.Uid(), pla.Port, plb.Pipe.Uid(), plb.Port)
}