aboutsummaryrefslogtreecommitdiff
path: root/src/dot.rs
blob: 97f4ab106baac96902f27cf7f3be35d126acb8b3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
use crate::*;

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct DcelDotOptions {
    pub twin: bool,
    pub next: bool,
    pub prev: bool,
}

impl DcelDotOptions {
    pub fn none() -> Self {
        Self {
            twin: false,
            next: false,
            prev: false,
        }
    }

    pub fn all() -> Self {
        Self {
            twin: true,
            next: true,
            prev: true,
        }
    }
}

pub fn dcel_write_dot<V>(
    dcel: &Dcel<V>,
    pos: impl Fn(&V) -> [f64; 2],
    name: impl Fn(&V, &mut Formatter) -> fmt::Result,
    f: &mut Formatter,
    opt: DcelDotOptions,
) -> fmt::Result {
    writeln!(f, "digraph DCEL {{")?;
    writeln!(f, "node [shape = circle]")?;
    //writeln!(f, "nodesep = 1")?;

    for shell in dcel.iter_bodies().flat_map(Lens::iter_shells) {
        for vertex in shell.iter_vertices() {
            let p = pos(vertex.data());

            writeln!(
                f,
                "vertex_{} [label=\"{}\", pos=\"{},{}!\"]",
                vertex.id(),
                DisplayFn(|f| name(vertex.data(), f)),
                p[0],
                p[1]
            )?;
        }

        for hedges in shell
            .iter_edges()
            .map(|x| x.half_edges())
            .flat_map(|[he1, he2]| [[he1, he2], [he2, he1]])
        {
            let ids = hedges.map(Lens::id);
            let vertices = hedges.map(|h| h.origin());
            let points = vertices.map(|v| pos(v.data()));

            let mut diff = [points[1][1] - points[0][1], points[1][0] - points[0][0]];

            // let len = (diff[0] * diff[0] + diff[1] * diff[1]).sqrt();
            diff[0] *= -0.075;
            diff[1] *= 0.075;

            let mid = [
                (points[1][0] + points[0][0]) / 2.0 + diff[0],
                (points[1][1] + points[0][1]) / 2.0 + diff[1],
            ];

            writeln!(
                f,
                "half_edge_{} [pos=\"{},{}!\", shape=point, width=0.01, height=0.01]",
                ids[0], mid[0], mid[1]
            )?;
            writeln!(
                f,
                "vertex_{} -> half_edge_{} [arrowhead=none]",
                vertices[0].id(),
                ids[0]
            )?;
            writeln!(
                f,
                "half_edge_{} -> vertex_{} [label=\"{}\"]",
                ids[0],
                vertices[1].id(),
                ids[0]
            )?;

            if opt.twin {
                writeln!(
                    f,
                    "half_edge_{} -> half_edge_{} [color=\"red\"]",
                    ids[0], ids[1]
                )?;
            }

            if opt.next {
                writeln!(
                    f,
                    "half_edge_{} -> half_edge_{} [color=\"green\"]",
                    ids[0],
                    hedges[0].next().id(),
                )?;
            }

            if opt.prev {
                writeln!(
                    f,
                    "half_edge_{} -> half_edge_{} [color=\"blue\"]",
                    ids[0],
                    hedges[0].prev().id(),
                )?;
            }
        }
    }

    writeln!(f, "}}")
}