-
Notifications
You must be signed in to change notification settings - Fork 1
/
fiducial-engine.py
executable file
·141 lines (117 loc) · 4.61 KB
/
fiducial-engine.py
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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#!/usr/bin/env python3
import argparse
import os
from textwrap import dedent
from svg_utils import svg_to_clipboard
################################################################################
# Constants
fiducial_styles = [
"xt16bfm",
]
svg_style = """
<style>
.background {
fill: #FFFFFF;
stroke: #FFFFFF;
stroke-width: 1px;
stroke-linejoin: round;
}
.foreground {
fill: #000000;
stroke: #000000;
stroke-width: 1px;
stroke-linejoin: round;
}
</style>
"""
################################################################################
# Fiducial - xt16bfm
def xt16bfm_canonicalize(value):
def rotate(value):
result = 0
for [index_a, index_b] in enumerate([6, 7, 0, 1, 2, 3, 4, 5]):
tmp = (value >> (index_b * 2)) & 0b11
tmp = (tmp + 1) & 0b11
result |= (tmp << (index_a * 2))
return result
def mirror(value):
result = 0
for [index_a, index_b] in enumerate([2, 1, 0, 7, 6, 5, 4, 3]):
tmp = (value >> (index_b * 2)) & 0b11
tmp = tmp ^ 0b01
result |= (tmp << (index_a * 2))
return result
return min([
value,
rotate(value),
rotate(rotate(value)),
rotate(rotate(rotate(value))),
mirror(value),
rotate(mirror(value)),
rotate(rotate(mirror(value))),
rotate(rotate(rotate(mirror(value)))),
])
################################################################################
# SVG document generator
def create_fiducial(fiducial_value, fiducial_style):
match fiducial_style:
case "xt16bfm":
svg_contents = ""
if fiducial_value == xt16bfm_canonicalize(fiducial_value):
for tile_position_index in range(0, 8):
tile_index = (fiducial_value >> (tile_position_index * 2)) & 0b11
[tile_u, tile_v] = [
[0, 0], [1, 0], [2, 0], [2, 1],
[2, 2], [1, 2], [0, 2], [0, 1],
][tile_position_index]
tile_size = 144
tile_x0 = 72 + (tile_u * tile_size)
tile_y0 = 72 + (tile_v * tile_size)
tile_x1 = tile_x0 + tile_size
tile_y1 = tile_y0 + tile_size
svg_contents += '<polygon class="foreground" points="{},{} {},{} {},{}" />'.format(
*[
[tile_x0, tile_y0, tile_x1, tile_y0, tile_x0, tile_y1],
[tile_x0, tile_y0, tile_x1, tile_y0, tile_x1, tile_y1],
[tile_x1, tile_y0, tile_x1, tile_y1, tile_x0, tile_y1],
[tile_x0, tile_y0, tile_x1, tile_y1, tile_x0, tile_y1],
][tile_index]
)
return dedent("""\
<svg width="576" height="576" viewBox="0 0 576 576" xmlns="http://www.w3.org/2000/svg">
{}
<g id="fiducial_{}_{}">
<rect class="background" x="0" y="0" width="576" height="576" />
<rect class="foreground" x="36" y="36" width="504" height="504" />
<rect class="background" x="54" y="54" width="468" height="468" />
<rect class="foreground" x="234" y="234" width="108" height="108" />
<rect class="background" x="252" y="252" width="72" height="72" />
<rect class="foreground" x="270" y="270" width="36" height="36" />
{}
</g>
</svg>
""").format(
svg_style,
fiducial_style,
fiducial_value,
svg_contents,
)
################################################################################
# Main
parser = argparse.ArgumentParser()
parser.add_argument("--command", type = str, )
parser.add_argument("--target", type = str, default = "stdout" )
parser.add_argument("--style", type = str, default = "xt16bfm")
parser.add_argument("--value", type = int, default = 0 )
args = parser.parse_args()
match args.command:
case "create-svg":
svg_document = create_fiducial(args.value, args.style)
match args.target:
case "stdout":
print(svg_document)
case "clipboard":
svg_to_clipboard(svg_document)
case "query-fiducial-styles":
for fiducial_style in fiducial_styles:
print(fiducial_style)