gim: make outgoing edges also be split along the rectangle
This commit is contained in:
parent
905b182467
commit
faf41c7386
@ -41,6 +41,24 @@ func abs(i int) int {
|
||||
return i
|
||||
}
|
||||
|
||||
// Abs returns the XY with all fields made positive, if they weren't already
|
||||
func (xy XY) Abs() XY {
|
||||
return XY{abs(xy[0]), abs(xy[1])}
|
||||
}
|
||||
|
||||
// Unit returns the XY with each field divided by its absolute value (i.e.
|
||||
// scaled down to 1 or -1). Fields which are 0 are left alone
|
||||
func (xy XY) Unit() XY {
|
||||
for i := range xy {
|
||||
if xy[i] > 0 {
|
||||
xy[i] = 1
|
||||
} else if xy[i] < 0 {
|
||||
xy[i] = -1
|
||||
}
|
||||
}
|
||||
return xy
|
||||
}
|
||||
|
||||
// Len returns the length (aka magnitude) of the XY as a vector, using the
|
||||
// Rounder to round to an int
|
||||
func (xy XY) Len(r Rounder) int {
|
||||
|
52
gim/line.go
52
gim/line.go
@ -40,59 +40,25 @@ var arrows = map[geo.XY]string{
|
||||
}
|
||||
|
||||
type line struct {
|
||||
from, to *box
|
||||
toI int
|
||||
from, to *box
|
||||
fromI, toI int
|
||||
}
|
||||
|
||||
// given the "primary" direction the line should be headed, picks a possible
|
||||
// secondary one which may be used to detour along the path in order to reach
|
||||
// the destination (in the case that the two boxes are diagonal from each other)
|
||||
func (l line) secondaryDir(primary geo.XY) geo.XY {
|
||||
fromRect, toRect := l.from.rect(), l.to.rect()
|
||||
rels := make([]int, len(geo.Units))
|
||||
for i, dir := range geo.Units {
|
||||
rels[i] = toRect.EdgeCoord(dir.Inv()) - fromRect.EdgeCoord(dir)
|
||||
if dir == geo.Up || dir == geo.Left {
|
||||
rels[i] *= -1
|
||||
}
|
||||
}
|
||||
|
||||
var secondary geo.XY
|
||||
var secondaryMax int
|
||||
var secondarySet bool
|
||||
for i, rel := range rels {
|
||||
if geo.Units[i] == primary {
|
||||
continue
|
||||
} else if geo.Units[i][0] == 0 && primary[0] == 0 {
|
||||
continue
|
||||
} else if geo.Units[i][1] == 0 && primary[1] == 0 {
|
||||
continue
|
||||
} else if !secondarySet || rel > secondaryMax {
|
||||
secondary = geo.Units[i]
|
||||
secondaryMax = rel
|
||||
secondarySet = true
|
||||
}
|
||||
}
|
||||
|
||||
return secondary
|
||||
func secondaryDir(flowDir, start, end geo.XY) geo.XY {
|
||||
var perpDir geo.XY
|
||||
perpDir[0], perpDir[1] = flowDir[1], flowDir[0]
|
||||
return end.Sub(start).Mul(perpDir.Abs()).Unit()
|
||||
}
|
||||
|
||||
//func (l line) startEnd(flowDir, secFlowDir geo.XY) (geo.XY, geo.XY) {
|
||||
// from, to := *(l.from), *(l.to)
|
||||
// start := from.rect().EdgeMidpoint(flowDir, rounder) // ezpz
|
||||
//}
|
||||
|
||||
func (l line) draw(term *terminal.Terminal, flowDir, secFlowDir geo.XY) {
|
||||
from, to := *(l.from), *(l.to)
|
||||
dirSec := l.secondaryDir(flowDir)
|
||||
|
||||
flowDirInv := flowDir.Inv()
|
||||
start := from.rect().Edge(flowDir, secFlowDir).Midpoint(rounder)
|
||||
|
||||
endSlot := l.toI*2 + 1
|
||||
endSlotXY := geo.XY{endSlot, endSlot}
|
||||
end := to.rect().Edge(flowDirInv, secFlowDir)[0].Add(secFlowDir.Mul(endSlotXY))
|
||||
|
||||
start := from.rect().Edge(flowDir, secFlowDir)[0].Add(secFlowDir.Scale(l.fromI*2 + 1))
|
||||
end := to.rect().Edge(flowDir.Inv(), secFlowDir)[0].Add(secFlowDir.Scale(l.toI*2 + 1))
|
||||
dirSec := secondaryDir(flowDir, start, end)
|
||||
mid := start.Midpoint(end, rounder)
|
||||
|
||||
along := func(xy, dir geo.XY) int {
|
||||
|
17
gim/main.go
17
gim/main.go
@ -17,7 +17,7 @@ import (
|
||||
// - Absolute positioning of some/all vertices
|
||||
|
||||
// TODO
|
||||
// - assign edges to "slots" on boxes
|
||||
// - in current example, order of edges leaving "a" is fucked
|
||||
// - edge values
|
||||
// - be able to draw circular graphs
|
||||
// - audit all steps, make sure everything is deterministic
|
||||
@ -76,8 +76,8 @@ func mkGraph() (*gg.Graph, gg.Value) {
|
||||
func main() {
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
term := terminal.New()
|
||||
term.Reset()
|
||||
term.HideCursor()
|
||||
//term.Reset()
|
||||
//term.HideCursor()
|
||||
|
||||
g, start := mkGraph()
|
||||
v := view{
|
||||
@ -88,9 +88,10 @@ func main() {
|
||||
center: geo.Zero.Midpoint(term.WindowSize(), rounder),
|
||||
}
|
||||
|
||||
for range time.Tick(frameperiod) {
|
||||
term.Reset()
|
||||
v.draw(term)
|
||||
term.Flush()
|
||||
}
|
||||
//for range time.Tick(frameperiod) {
|
||||
term.Reset()
|
||||
v.draw(term)
|
||||
term.Flush()
|
||||
//}
|
||||
time.Sleep(1 * time.Hour)
|
||||
}
|
||||
|
18
gim/view.go
18
gim/view.go
@ -146,13 +146,29 @@ func (view *view) draw(term *terminal.Terminal) {
|
||||
primPos += maxPrim + primPadding
|
||||
}
|
||||
|
||||
// returns the index of this edge in from's Out
|
||||
// TODO this might not be deterministic? Out is never ordered technically
|
||||
findFromI := func(from *gg.Vertex, e gg.Edge) int {
|
||||
for i, fe := range from.Out {
|
||||
if fe == e {
|
||||
return i
|
||||
}
|
||||
}
|
||||
panic("edge not found in from.Out")
|
||||
}
|
||||
|
||||
// create lines
|
||||
var lines []line
|
||||
for _, b := range boxes {
|
||||
v := boxesM[b]
|
||||
for i, e := range v.In {
|
||||
bFrom := boxesMr[e.From]
|
||||
lines = append(lines, line{from: bFrom, to: b, toI: i})
|
||||
lines = append(lines, line{
|
||||
from: bFrom,
|
||||
fromI: findFromI(e.From, e),
|
||||
to: b,
|
||||
toI: i,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user