Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
SmilyOrg committed May 10, 2024
1 parent f2384e2 commit 7ea675f
Show file tree
Hide file tree
Showing 3 changed files with 449 additions and 345 deletions.
77 changes: 77 additions & 0 deletions internal/layout/dag/dag.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package dag

import (
"photofield/internal/image"
)

type Id = image.ImageId

type Photo struct {
Id Id
AspectRatio float32
Aux bool
}

type Aux struct {
Text string
}

type Index int

type Node struct {
Index Index
ShortestParent Index
Cost float32
TotalAspect float32
}

// type Graph[T Item] struct {
// items []Item
// q *deque.Deque[Index]
// nodes map[Index]Node
// }

// func New[T Item](items []Item) *Graph[T] {
// g := &Graph[T]{
// items: items,
// q: deque.New[Index](len(items) / 4),
// nodes: make(map[Index]Node, len(items)),
// }
// g.nodes[-1] = Node{
// ItemIndex: -1,
// Cost: 0,
// TotalAspect: 0,
// }
// g.q.PushBack(0)
// return g
// }

// func (g *Graph[T]) Next() Node {
// idx := g.q.PopFront()
// return g.nodes[idx]
// }

// func (g *Graph[T]) Add(i Index, cost float32) {
// n, ok := g.nodes[i]
// if ok {
// if n.Cost > cost {
// n.Cost = cost
// n.ShortestParent = i
// // fmt.Printf(" node %d exists, lower cost %f\n", i, n.Cost)
// }
// // fmt.Printf(" node %d exists, keep cost %f\n", i, n.Cost)
// // }
// } else {
// n = &FlexNode{
// Index: i,
// Cost: totalCost,
// TotalAspect: float32(totalAspect),
// Shortest: node,
// }
// indexToNode[i] = n
// if i < len(photos)-1 {
// q.PushBack(n)
// }
// // fmt.Printf(" node %d added with cost %f\n", i, n.Cost)
// }
// }
128 changes: 80 additions & 48 deletions internal/layout/flex.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,37 +26,37 @@ type FlexAux struct {
}

type FlexNode struct {
Index int
Cost float32
TotalAspect float32
Shortest *FlexNode
Index int
Cost float32
TotalAspect float32
ShortestParent int
}

func (n *FlexNode) Dot() string {
// dot := ""

stack := []*FlexNode{n}
visited := make(map[int]bool)
dot := ""
for len(stack) > 0 {
node := stack[0]
stack = stack[1:]
if visited[node.Index] {
continue
}
visited[node.Index] = true
// dot += fmt.Sprintf("%d [label=\"%d\\nCost: %.0f\\nHeight: %.0f\\nTotalAspect: %.2f\"];\n", node.Index, node.Index, node.Cost, node.ImageHeight, node.TotalAspect)
// for _, link := range node.Links {
// attr := ""
// if link.Shortest == node {
// attr = " [penwidth=3]"
// }
// dot += fmt.Sprintf("\t%d -> %d%s;\n", node.Index, link.Index, attr)
// stack = append(stack, link)
// }
}
return dot
}
// func (n *FlexNode) Dot() string {
// // dot := ""

// stack := []*FlexNode{n}
// visited := make(map[int]bool)
// dot := ""
// for len(stack) > 0 {
// node := stack[0]
// stack = stack[1:]
// if visited[node.Index] {
// continue
// }
// visited[node.Index] = true
// // dot += fmt.Sprintf("%d [label=\"%d\\nCost: %.0f\\nHeight: %.0f\\nTotalAspect: %.2f\"];\n", node.Index, node.Index, node.Cost, node.ImageHeight, node.TotalAspect)
// // for _, link := range node.Links {
// // attr := ""
// // if link.Shortest == node {
// // attr = " [penwidth=3]"
// // }
// // dot += fmt.Sprintf("\t%d -> %d%s;\n", node.Index, link.Index, attr)
// // stack = append(stack, link)
// // }
// }
// return dot
// }

func LayoutFlex(infos <-chan image.SourcedInfo, layout Layout, scene *render.Scene, source *image.Source) {

Expand Down Expand Up @@ -92,6 +92,7 @@ func LayoutFlex(infos <-chan image.SourcedInfo, layout Layout, scene *render.Sce

scene.Photos = scene.Photos[:0]
photos := make([]FlexPhoto, 0)
// photos2 := make([]dag.Item, 0)

layoutCounter := metrics.Counter{
Name: "layout",
Expand Down Expand Up @@ -139,23 +140,51 @@ func LayoutFlex(infos <-chan image.SourcedInfo, layout Layout, scene *render.Sce
AspectRatio: float32(info.Width) / float32(info.Height),
}
photos = append(photos, photo)
// photos2 = append(photos2, dag.Item{
// Id: info.Id,
// AspectRatio: float32(info.Width) / float32(info.Height),
// })
layoutCounter.Set(len(photos))
}

root := &FlexNode{
Index: -1,
Cost: 0,
TotalAspect: 0,
// root := &

q := deque.New[int](len(photos) / 4)
q.PushBack(-1)
indexToNode := make(map[int]FlexNode, len(photos))
indexToNode[-1] = FlexNode{
Index: -1,
Cost: 0,
TotalAspect: 0,
ShortestParent: -1,
}

q := deque.New[*FlexNode](len(photos) / 4)
q.PushBack(root)
indexToNode := make(map[int]*FlexNode, len(photos))
// g := dag.New(photos2)

maxLineWidth := rect.W

// for node := g.Next(); node != nil; node = g.Next() {
// totalAspect := 0.
// fallback := false

// for i := node.ItemIndex + 1; i < len(photos2); i++ {
// photo := photos2[i]
// totalAspect += float64(photo.AspectRatio)
// totalSpacing := layout.ImageSpacing * float64(i-1-node.ItemIndex)
// photoHeight := (maxLineWidth - totalSpacing) / totalAspect
// valid := photoHeight >= minHeight && photoHeight <= maxHeight || i == len(photos)-1 || fallback
// badness := math.Abs(photoHeight - idealHeight)
// cost := badness*badness + 10
// if i < len(photos2)-1 && photos2[i+1].Aux {
// cost *= 0.1
// }

// if valid {
// n := g.Add(i, node.Cost + float32(cost))

for q.Len() > 0 {
node := q.PopFront()
// node.Index := q.PopFront()
node := indexToNode[q.PopFront()]
totalAspect := 0.
fallback := false

Expand Down Expand Up @@ -186,21 +215,22 @@ func LayoutFlex(infos <-chan image.SourcedInfo, layout Layout, scene *render.Sce
if n.Cost > totalCost {
n.Cost = totalCost
n.TotalAspect = float32(totalAspect)
n.Shortest = node
n.ShortestParent = node.Index
// fmt.Printf(" node %d exists, lower cost %f\n", i, n.Cost)
}
indexToNode[i] = n
// fmt.Printf(" node %d exists, keep cost %f\n", i, n.Cost)
// }
} else {
n = &FlexNode{
Index: i,
Cost: totalCost,
TotalAspect: float32(totalAspect),
Shortest: node,
n = FlexNode{
Index: i,
Cost: totalCost,
TotalAspect: float32(totalAspect),
ShortestParent: node.Index,
}
indexToNode[i] = n
if i < len(photos)-1 {
q.PushBack(n)
q.PushBack(i)
}
// fmt.Printf(" node %d added with cost %f\n", i, n.Cost)
}
Expand Down Expand Up @@ -229,11 +259,13 @@ func LayoutFlex(infos <-chan image.SourcedInfo, layout Layout, scene *render.Sce
// fmt.Println(dot)

// Trace back the shortest path
shortestPath := make([]*FlexNode, 0)
for node := indexToNode[len(photos)-1]; node != nil; {
// fmt.Printf("node %d cost %f\n", node.Index, node.Cost)
shortestPath := make([]FlexNode, 0)

for parent := len(photos) - 1; parent > 0; {
node := indexToNode[parent]
// fmt.Printf("%d node %d cost %f\n", parent, node.Index, node.Cost)
shortestPath = append(shortestPath, node)
node = node.Shortest
parent = node.ShortestParent
}

// Finally, place the photos based on the shortest path breaks
Expand Down

0 comments on commit 7ea675f

Please sign in to comment.