// caller is responsible for aligning these func connect2DSameDirTrackPieces(trackEnd geo.Vector, stationStart geo.Vector) []tracks.Element { if trackEnd.Dir != stationStart.Dir { log.Panic("track end and station start are not the same", trackEnd, stationStart) } if stationStart.Point[0] == trackEnd.Point[0] && stationStart.Point[1] == trackEnd.Point[1] { return []tracks.Element{} } if stationStart.Dir == tracks.DIR_STRAIGHT { // directionDelta: 0, stationStart: (3, 4). ok straight points are ((x < 3), 4) if stationStart.Point[1] == trackEnd.Point[1] { // points have same Y axis if trackEnd.Point[0] < stationStart.Point[0] { // trackEnd directly behind stationStart. proceed forward to // the station! elems := make([]tracks.Element, round(stationStart.Point[0]-trackEnd.Point[0])) count := 0 for i := trackEnd.Point[0]; i < stationStart.Point[0]; i++ { elems[count] = tracks.Element{ Segment: tracks.TS_MAP[tracks.ELEM_FLAT], } count += 1 } return elems } else { // track end ahead of station start...not great, turn to the // right. elems := []tracks.Element{tracks.Element{ Segment: tracks.TS_MAP[tracks.ELEM_RIGHT_QUARTER_TURN_3_TILES], }} v := geo.AdvanceVector(trackEnd, elems[0].Segment) return append(elems, connect2DTrackPieces(v, stationStart)...) } } else if trackEnd.Point[1] < stationStart.Point[1] { // trackEnd below the station start if trackEnd.Point[0] < stationStart.Point[0]-5 && trackEnd.Point[1] < stationStart.Point[1]-5 { // Can get there with a left turn and a right turn elems := []tracks.Element{tracks.Element{ Segment: tracks.TS_MAP[tracks.ELEM_LEFT_QUARTER_TURN_3_TILES], }} v := geo.AdvanceVector(trackEnd, elems[0].Segment) return append(elems, connect2DTrackPieces(v, stationStart)...) } } else { // trackEnd above the station start if trackEnd.Point[0] > stationStart.Point[0]-5 && trackEnd.Point[1] < stationStart.Point[1]+5 { // Can get there with a right turn and a left turn elems := []tracks.Element{tracks.Element{ Segment: tracks.TS_MAP[tracks.ELEM_RIGHT_QUARTER_TURN_3_TILES], }} v := geo.AdvanceVector(trackEnd, elems[0].Segment) return append(elems, connect2DTrackPieces(v, stationStart)...) } } } else { log.Panic("direction didn't match", stationStart.Dir) } return []tracks.Element{} }
func connect2DOppositeDirTrackPieces(trackEnd geo.Vector, stationStart geo.Vector) []tracks.Element { if trackEnd.Point[1] >= stationStart.Point[1] { if trackEnd.Point[1] >= stationStart.Point[1]+4 { if trackEnd.Point[0] > stationStart.Point[0] { elems := make([]tracks.Element, round(trackEnd.Point[0]-stationStart.Point[0])) count := 0 v := trackEnd for i := trackEnd.Point[0]; i > stationStart.Point[0]; i-- { elems[count] = tracks.Element{ Segment: tracks.TS_MAP[tracks.ELEM_FLAT], } v = geo.AdvanceVector(v, elems[count].Segment) count += 1 } return append(elems, connect2DTrackPieces(v, stationStart)...) } else { return leftTurn(trackEnd, stationStart) } } else { return rightTurn(trackEnd, stationStart) } } else { if trackEnd.Point[1] < stationStart.Point[1]-4 { if trackEnd.Point[0] > stationStart.Point[0] { elems := make([]tracks.Element, round(trackEnd.Point[0]-stationStart.Point[0])) v := trackEnd count := 0 for i := trackEnd.Point[0]; i > stationStart.Point[0]; i-- { elems[count] = tracks.Element{ Segment: tracks.TS_MAP[tracks.ELEM_FLAT], } v = geo.AdvanceVector(v, elems[count].Segment) count += 1 } return append(elems, connect2DTrackPieces(v, stationStart)...) } else { return rightTurn(trackEnd, stationStart) } } else { return leftTurn(trackEnd, stationStart) } } }
func straight(trackEnd geo.Vector, stationStart geo.Vector) []tracks.Element { elem := tracks.Element{ Segment: tracks.TS_MAP[tracks.ELEM_FLAT], } v := geo.AdvanceVector(trackEnd, elem.Segment) return append([]tracks.Element{elem}, connect2DTrackPieces(v, stationStart)...) }
func leftTurn(trackEnd geo.Vector, stationStart geo.Vector) []tracks.Element { elem := tracks.Element{ Segment: tracks.TS_MAP[tracks.ELEM_LEFT_QUARTER_TURN_3_TILES], } v := geo.AdvanceVector(trackEnd, elem.Segment) return append([]tracks.Element{elem}, connect2DTrackPieces(v, stationStart)...) }
// Add pieces to the track to remove the slope and the bank func straightenTrack(trackPiece tracks.Element, trackEnd geo.Vector) ([]tracks.Element, geo.Vector) { if trackPiece.Segment.EndingBank == tracks.TRACK_BANK_NONE && trackPiece.Segment.OutputDegree == tracks.TRACK_NONE { return []tracks.Element{}, trackEnd } if trackPiece.Segment.OutputDegree == tracks.TRACK_UP_60 { elem := tracks.Element{ Segment: tracks.TS_MAP[tracks.ELEM_60_DEG_UP_TO_25_DEG_UP], } v := geo.AdvanceVector(trackEnd, elem.Segment) result, finalV := straightenTrack(elem, v) return append([]tracks.Element{elem}, result...), finalV } else if trackPiece.Segment.OutputDegree == tracks.TRACK_UP_25 { elem := tracks.Element{ Segment: tracks.TS_MAP[tracks.ELEM_25_DEG_UP_TO_FLAT], } v := geo.AdvanceVector(trackEnd, elem.Segment) result, finalV := straightenTrack(elem, v) return append([]tracks.Element{elem}, result...), finalV } else if trackPiece.Segment.OutputDegree == tracks.TRACK_DOWN_25 { elem := tracks.Element{ Segment: tracks.TS_MAP[tracks.ELEM_25_DEG_DOWN_TO_FLAT], } v := geo.AdvanceVector(trackEnd, elem.Segment) result, finalV := straightenTrack(elem, v) return append([]tracks.Element{elem}, result...), finalV } else if trackPiece.Segment.OutputDegree == tracks.TRACK_DOWN_60 { elem := tracks.Element{ Segment: tracks.TS_MAP[tracks.ELEM_60_DEG_DOWN_TO_25_DEG_DOWN], } v := geo.AdvanceVector(trackEnd, elem.Segment) result, finalV := straightenTrack(elem, v) return append([]tracks.Element{elem}, result...), finalV } if trackPiece.Segment.EndingBank == tracks.TRACK_BANK_LEFT { elem := tracks.Element{ Segment: tracks.TS_MAP[tracks.ELEM_LEFT_BANK_TO_FLAT], } v := geo.AdvanceVector(trackEnd, elem.Segment) result, finalV := straightenTrack(elem, v) return append([]tracks.Element{elem}, result...), finalV } else if trackPiece.Segment.EndingBank == tracks.TRACK_BANK_RIGHT { elem := tracks.Element{ Segment: tracks.TS_MAP[tracks.ELEM_RIGHT_BANK_TO_FLAT], } v := geo.AdvanceVector(trackEnd, elem.Segment) result, finalV := straightenTrack(elem, v) return append([]tracks.Element{elem}, result...), finalV } panic("unknown output degree") }