Allow reading svg files

This commit is contained in:
Arne Keller 2019-04-01 19:05:18 +02:00
parent 1ede7ee2bc
commit 2c0d20eae4
5 changed files with 439 additions and 6 deletions

99
Cargo.lock generated
View File

@ -8,6 +8,7 @@ dependencies = [
"geo 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "geo 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
"structopt 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)", "structopt 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)",
"svg 0.5.12 (registry+https://github.com/rust-lang/crates.io-index)", "svg 0.5.12 (registry+https://github.com/rust-lang/crates.io-index)",
"svgdom 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@ -92,6 +93,14 @@ dependencies = [
"synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "float-cmp"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "geo" name = "geo"
version = "0.12.0" version = "0.12.0"
@ -125,6 +134,14 @@ name = "libc"
version = "0.2.51" version = "0.2.51"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "log"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "num-integer" name = "num-integer"
version = "0.1.39" version = "0.1.39"
@ -151,6 +168,22 @@ name = "pdqselect"
version = "0.1.0" version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "phf"
version = "0.7.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"phf_shared 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "phf_shared"
version = "0.7.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"siphasher 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "0.4.27" version = "0.4.27"
@ -169,9 +202,17 @@ dependencies = [
[[package]] [[package]]
name = "redox_syscall" name = "redox_syscall"
version = "0.1.51" version = "0.1.52"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "roxmltree"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"xmlparser 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "rstar" name = "rstar"
version = "0.2.0" version = "0.2.0"
@ -187,6 +228,21 @@ name = "rustc-demangle"
version = "0.1.13" version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "simplecss"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "siphasher"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "slab"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "structopt" name = "structopt"
version = "0.2.15" version = "0.2.15"
@ -212,6 +268,27 @@ name = "svg"
version = "0.5.12" version = "0.5.12"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "svgdom"
version = "0.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"roxmltree 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"simplecss 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"svgtypes 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "svgtypes"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"float-cmp 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"phf 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "syn" name = "syn"
version = "0.15.29" version = "0.15.29"
@ -255,7 +332,7 @@ version = "0.1.42"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.52 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
@ -293,6 +370,11 @@ name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0" version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "xmlparser"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[metadata] [metadata]
"checksum autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a6d640bee2da49f60a4068a7fae53acde8982514ab7bae8b8cea9e88cbcfd799" "checksum autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a6d640bee2da49f60a4068a7fae53acde8982514ab7bae8b8cea9e88cbcfd799"
"checksum backtrace 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "cd5a90e2b463010cd0e0ce9a11d4a9d5d58d9f41d4a6ba3dcaf9e68b466e88b4" "checksum backtrace 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "cd5a90e2b463010cd0e0ce9a11d4a9d5d58d9f41d4a6ba3dcaf9e68b466e88b4"
@ -304,22 +386,32 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e" "checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e"
"checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2" "checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2"
"checksum failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1" "checksum failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1"
"checksum float-cmp 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "134a8fa843d80a51a5b77d36d42bc2def9edcb0262c914861d08129fd1926600"
"checksum geo 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8cfb3011a87e562d59a3e3e2e2595a867780ff7ad618fbb2579f03ea038961a2" "checksum geo 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8cfb3011a87e562d59a3e3e2e2595a867780ff7ad618fbb2579f03ea038961a2"
"checksum geo-types 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "909178c1a808c8d77571b92dc13cf485b827412e2078ded759942bae3563a4d4" "checksum geo-types 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "909178c1a808c8d77571b92dc13cf485b827412e2078ded759942bae3563a4d4"
"checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" "checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205"
"checksum libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)" = "bedcc7a809076656486ffe045abeeac163da1b558e963a31e29fbfbeba916917" "checksum libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)" = "bedcc7a809076656486ffe045abeeac163da1b558e963a31e29fbfbeba916917"
"checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6"
"checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea" "checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea"
"checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1" "checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1"
"checksum num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1a23f0ed30a54abaa0c7e83b1d2d87ada7c3c23078d1d87815af3e3b6385fbba" "checksum num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1a23f0ed30a54abaa0c7e83b1d2d87ada7c3c23078d1d87815af3e3b6385fbba"
"checksum pdqselect 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ec91767ecc0a0bbe558ce8c9da33c068066c57ecc8bb8477ef8c1ad3ef77c27" "checksum pdqselect 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ec91767ecc0a0bbe558ce8c9da33c068066c57ecc8bb8477ef8c1ad3ef77c27"
"checksum phf 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "b3da44b85f8e8dfaec21adae67f95d93244b2ecf6ad2a692320598dcc8e6dd18"
"checksum phf_shared 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "234f71a15de2288bcb7e3b6515828d22af7ec8598ee6d24c3b526fa0a80b67a0"
"checksum proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)" = "4d317f9caece796be1980837fd5cb3dfec5613ebdb04ad0956deea83ce168915" "checksum proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)" = "4d317f9caece796be1980837fd5cb3dfec5613ebdb04ad0956deea83ce168915"
"checksum quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "cdd8e04bd9c52e0342b406469d494fcb033be4bdbe5c606016defbb1681411e1" "checksum quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "cdd8e04bd9c52e0342b406469d494fcb033be4bdbe5c606016defbb1681411e1"
"checksum redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)" = "423e376fffca3dfa06c9e9790a9ccd282fafb3cc6e6397d01dbf64f9bacc6b85" "checksum redox_syscall 0.1.52 (registry+https://github.com/rust-lang/crates.io-index)" = "d32b3053e5ced86e4bc0411fec997389532bf56b000e66cb4884eeeb41413d69"
"checksum roxmltree 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "53b0200cbfa8b3f6cfd6076592717d697a1ddc57cb2a8fbfd3d133c06011b579"
"checksum rstar 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "120bfe4837befb82c5a637a5a8c490a27d25524ac19fffec5b4e555ca6e36ee8" "checksum rstar 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "120bfe4837befb82c5a637a5a8c490a27d25524ac19fffec5b4e555ca6e36ee8"
"checksum rustc-demangle 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "adacaae16d02b6ec37fdc7acfcddf365978de76d1983d3ee22afc260e1ca9619" "checksum rustc-demangle 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "adacaae16d02b6ec37fdc7acfcddf365978de76d1983d3ee22afc260e1ca9619"
"checksum simplecss 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "135685097a85a64067df36e28a243e94a94f76d829087ce0be34eeb014260c0e"
"checksum siphasher 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0b8de496cf83d4ed58b6be86c3a275b8602f6ffe98d3024a869e124147a9a3ac"
"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
"checksum structopt 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)" = "3d0760c312538987d363c36c42339b55f5ee176ea8808bbe4543d484a291c8d1" "checksum structopt 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)" = "3d0760c312538987d363c36c42339b55f5ee176ea8808bbe4543d484a291c8d1"
"checksum structopt-derive 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)" = "528aeb7351d042e6ffbc2a6fb76a86f9b622fdf7c25932798e7a82cb03bc94c6" "checksum structopt-derive 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)" = "528aeb7351d042e6ffbc2a6fb76a86f9b622fdf7c25932798e7a82cb03bc94c6"
"checksum svg 0.5.12 (registry+https://github.com/rust-lang/crates.io-index)" = "a863ec1f8e7cfd4ea449f77445cca06aac240b9a677ccf12b0f65ef020db52c7" "checksum svg 0.5.12 (registry+https://github.com/rust-lang/crates.io-index)" = "a863ec1f8e7cfd4ea449f77445cca06aac240b9a677ccf12b0f65ef020db52c7"
"checksum svgdom 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3ffe3c59d84b307fc361bbf0baff2aa6f6d7c946fdd4f1fbbcbb7efcd04b0334"
"checksum svgtypes 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "06280cc80ac6d6be32d497f068c40a25552cc837519265edab70d9040e64c52b"
"checksum syn 0.15.29 (registry+https://github.com/rust-lang/crates.io-index)" = "1825685f977249735d510a242a6727b46efe914bb67e38d30c071b1b72b1d5c2" "checksum syn 0.15.29 (registry+https://github.com/rust-lang/crates.io-index)" = "1825685f977249735d510a242a6727b46efe914bb67e38d30c071b1b72b1d5c2"
"checksum synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "73687139bf99285483c96ac0add482c3776528beac1d97d444f6e91f203a2015" "checksum synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "73687139bf99285483c96ac0add482c3776528beac1d97d444f6e91f203a2015"
"checksum textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "307686869c93e71f94da64286f9a9524c0f308a9e1c87a583de8e9c9039ad3f6" "checksum textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "307686869c93e71f94da64286f9a9524c0f308a9e1c87a583de8e9c9039ad3f6"
@ -331,3 +423,4 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0" "checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0"
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
"checksum xmlparser 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ecec95f00fb0ff019153e64ea520f87d1409769db3e8f4db3ea588638a3e1cee"

View File

@ -14,3 +14,4 @@ geo = "0.12"
svg = "0.5.11" svg = "0.5.11"
chrono = "0.4.6" chrono = "0.4.6"
structopt = { version = "0.2", default-features = false } structopt = { version = "0.2", default-features = false }
svgdom = "0.16.1"

View File

@ -145,7 +145,7 @@ Zunächst kann man feststellen, dass der letzte Abschnitt jeder Route zum Bus im
Um den letzten Zeitpunkt, bei dem sie den Bus gerade noch erwischt, zu bestimmen, kann man die Wurzel in der letzen Gleichung gleich Null setzen. Wenn man nach $y_{B}$ auflöst, erhält man die Position des Busses, bei dessen Durchquerung Lisa anfangen sollte zu laufen. So kann man für jeden Startpunkt berechnen, wann Lisa spätestens von dort loslaufen müsste. Um den letzten Zeitpunkt, bei dem sie den Bus gerade noch erwischt, zu bestimmen, kann man die Wurzel in der letzen Gleichung gleich Null setzen. Wenn man nach $y_{B}$ auflöst, erhält man die Position des Busses, bei dessen Durchquerung Lisa anfangen sollte zu laufen. So kann man für jeden Startpunkt berechnen, wann Lisa spätestens von dort loslaufen müsste.
Außerdem wird Lisa auf einer optimalen Route vor dem letzten Abschnitt immer von einer Polygonecke zur nächsten gehen. Andernfalls würde sie in Kurven um jene Ecken wertvolle Zeit verschwenden. Der letzte Abschnitt ihrer Route trifft die y-Achse immer in einem 60\degree-Winkel (siehe Abbildungen). Dieser Winkel ist vom Verhältnis der Geschwindigkeiten von Lisa und dem Bus abhängig: $cos(60\degree) = \frac{15}{30}$. Außerdem wird Lisa auf einer optimalen Route vor dem letzten Abschnitt immer von einer Polygonecke zur nächsten gehen. Andernfalls würde sie in Kurven um jene Ecken wertvolle Zeit verschwenden. Der letzte Abschnitt ihrer Route trifft die y-Achse immer in einem 60\degree-Winkel (siehe Abb. \ref{fig:winkel}). Dieser Winkel ist vom Verhältnis der Geschwindigkeiten von Lisa und dem Bus abhängig: $cos(60\degree) = \frac{15}{30}$.
\begin{figure}[H] \begin{figure}[H]
\centering \centering
@ -228,6 +228,9 @@ Wenn in jedem Schritt jede andere Polygonecke berücksichtigt wird, hat der Algo
Das Programm liest die Problemstellung von der Standardeingabe ein. Die grafische Ausgabe wird in die Standardausgabe geschrieben. Wird $-t$ übergeben, kann die Ausgabe in einem \LaTeX-Dokument verwendet werden. Standardmäßig wird ein SVG-Dokument erzeugt. Mit $-s$ werden auch Zwischenlösungen im aktuellen Ordner als SVG-Dateien gespeichert. Falls man die Geschwindigkeit von Lisa oder dem Bus verändern will, kann man dies mit $-l$ bzw. $-b$ tun. Für zusätzliche Debug-Ausgaben kann man $-d$ verwenden. Die Standardoptionen $-h$ und $-V$ zeigen die Hilfe und die Version des Programms an. Das Programm liest die Problemstellung von der Standardeingabe ein. Die grafische Ausgabe wird in die Standardausgabe geschrieben. Wird $-t$ übergeben, kann die Ausgabe in einem \LaTeX-Dokument verwendet werden. Standardmäßig wird ein SVG-Dokument erzeugt. Mit $-s$ werden auch Zwischenlösungen im aktuellen Ordner als SVG-Dateien gespeichert. Falls man die Geschwindigkeit von Lisa oder dem Bus verändern will, kann man dies mit $-l$ bzw. $-b$ tun. Für zusätzliche Debug-Ausgaben kann man $-d$ verwenden. Die Standardoptionen $-h$ und $-V$ zeigen die Hilfe und die Version des Programms an.
\lstinputlisting[caption=Hilfetext des Programmes,frame=single,breaklines=true]{help.txt} \lstinputlisting[caption=Hilfetext des Programmes,frame=single,breaklines=true]{help.txt}
\subsection{Eigene Beispiele}
Das vorgegebene Eingabeformat ist mühsam zu schreiben. Daher kann das Programm auch SVG-Dateien einlesen. Punkte werden als Startpunkte interpretiert, sonstige Pfade sind Hindernisse.
\section{Umsetzung} \section{Umsetzung}
Das Programm durchsucht in einer optimierten Breitensuche alle Wege, die über Polygonecken führen. Priorisiert (mit einem binären Max-Heap) werden jene Wege, bei denen Lisa theoretisch am längsten warten könnte. Um die Route abzuschließen, probiert das Programm danach immer, einen optimalen Weg zur y-Achse zu finden (dieser trifft sie im 60\degree-Winkel, wie oben beschrieben). Die Route, bei dem Lisa sich am meisten Zeit lassen kann, wird gespeichert, falls nicht schon eine bessere Lösung gefunden wurde. Die Suche ist beendet, sobald alle unvollständigen Routen die beste Wartezeit nicht mehr verbessern können. Das Programm durchsucht in einer optimierten Breitensuche alle Wege, die über Polygonecken führen. Priorisiert (mit einem binären Max-Heap) werden jene Wege, bei denen Lisa theoretisch am längsten warten könnte. Um die Route abzuschließen, probiert das Programm danach immer, einen optimalen Weg zur y-Achse zu finden (dieser trifft sie im 60\degree-Winkel, wie oben beschrieben). Die Route, bei dem Lisa sich am meisten Zeit lassen kann, wird gespeichert, falls nicht schon eine bessere Lösung gefunden wurde. Die Suche ist beendet, sobald alle unvollständigen Routen die beste Wartezeit nicht mehr verbessern können.

View File

@ -1,5 +1,8 @@
use super::*; use super::*;
use svgdom::{AttributeId, AttributeValue, Document, ElementId, FilterSvg, PathSegment, QName};
use std::error::Error;
use std::io; use std::io;
use std::io::prelude::*; use std::io::prelude::*;
@ -15,9 +18,15 @@ pub(crate) fn read_input() -> InputData {
fn read_stdin() -> InputData { fn read_stdin() -> InputData {
let stdin = io::stdin(); let stdin = io::stdin();
let stdin = stdin.lock(); let mut stdin = stdin.lock();
let mut input = String::new();
stdin.read_to_string(&mut input).unwrap();
let mut lines = stdin.lines().map(Result::unwrap); // SVG?
if let Ok(data) = read_svg(&input) {
return data;
}
let mut lines = input.split('\n');
let polygon_count = lines.next().unwrap().parse().unwrap(); let polygon_count = lines.next().unwrap().parse().unwrap();
let mut polygons = Vec::with_capacity(polygon_count); let mut polygons = Vec::with_capacity(polygon_count);
@ -57,6 +66,55 @@ fn read_stdin() -> InputData {
} }
} }
fn read_svg(input: &str) -> Result<InputData, Box<Error>> {
let svg = Document::from_str(input)?;
let svg = svg.svg_element().unwrap();
let mut house = None;
let mut polys = Vec::new();
for (id, node) in svg.descendants().svg() {
//eprintln!("<{:?} /> {:?}", id, node);
if id == ElementId::Path && *node.parent().unwrap().tag_name() != QName::Id(ElementId::Marker) {
let attrs = node.attributes();
if let Some(&AttributeValue::Path(ref path)) = attrs.get_value(AttributeId::D) {
let mut path = path.clone();
path.conv_to_absolute();
let mut points = Vec::with_capacity(path.0.len() - 1);
for p in &path.0 {
match p {
PathSegment::MoveTo { x, y, .. } => {
points.push(Point::new(*x, -*y));
},
PathSegment::LineTo { x, y, .. } => {
points.push(Point::new(*x, -*y));
},
PathSegment::VerticalLineTo { y, .. } => {
points.push(Point::new(points.last().unwrap().x(), -*y));
},
PathSegment::HorizontalLineTo { x, .. } => {
points.push(Point::new(*x, points.last().unwrap().y()));
},
PathSegment::ClosePath { .. } => break,
_ => unimplemented!("nicht unterstütztes SVG-Element: {:?}", p)
}
}
if points.len() == 1 {
// Startpunkt
house = Some(points[0]);
} else {
// Hindernis
polys.push(Polygon::new(points.into(), vec![]));
}
}
}
}
Ok(InputData {
start: house.expect("kein Startpunkt definiert!"),
polys
})
}
fn _custom_input() -> InputData { fn _custom_input() -> InputData {
let mut polys = vec![]; let mut polys = vec![];
polys.push(Polygon::new( polys.push(Polygon::new(

278
welt1.svg Normal file
View File

@ -0,0 +1,278 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="510mm"
height="597mm"
viewBox="0 0 510 597"
version="1.1"
id="svg8"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
sodipodi:docname="welt1.svg">
<defs
id="defs2">
<marker
inkscape:stockid="DotL"
orient="auto"
refY="0"
refX="0"
id="DotL"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path920"
d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
style="fill:#00ff00;fill-opacity:1;fill-rule:evenodd;stroke:#00ff00;stroke-width:1.00000003pt;stroke-opacity:1"
transform="matrix(0.8,0,0,0.8,5.92,0.8)"
inkscape:connector-curvature="0" />
</marker>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.7"
inkscape:cx="787.74866"
inkscape:cy="791.88849"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1920"
inkscape:window-height="1015"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,300)">
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 25.648656,-14.963559 30.238097,-92.226181 32.127975,92.226181 z"
id="path10"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 86.8808,-71.659983 3.779766,44.979174 41.577384,-45.735124 z"
id="path12"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 96.708186,-129.11237 -12.473221,35.907747 9.449411,14.74107 41.199404,-20.78869 -12.09524,-16.252977 z"
id="path14"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 20.73497,-199.7939 34.39583,22.30059 6.04762,-30.99405 z"
id="path16"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 45.303419,-127.97843 24.190476,-54.80655 30.994055,46.49107 z"
id="path18"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 115.60699,-157.46057 -6.42559,26.45833 10.20535,8.69345 z"
id="path20"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 63.824247,-122.3088 v 15.87501 l 11.33929,-0.37797 -2.64583,-18.14287 z"
id="path22"
inkscape:connector-curvature="0" />
<path
style="fill:#00ff00;fill-opacity:1;stroke:#00ff00;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#DotL);paint-order:normal"
d="M 464.83409,288.31171 Z"
id="path30"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 160.93063,37.255861 30.23809,-92.226197 32.12798,92.226197 z"
id="path10-3"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 222.16277,-19.440569 3.77977,44.97918 41.57737,-45.73513 z"
id="path12-6"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 295.53546,2.6812207 -12.47322,35.9077403 9.44941,14.74107 41.19939,-20.7887 -12.09523,-16.25296 z"
id="path14-7"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 156.01694,-147.57449 34.39583,22.30059 6.04762,-30.99405 z"
id="path16-5"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 180.58539,-75.759013 24.19048,-54.806557 30.99405,46.491087 z"
id="path18-3"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 250.88896,-105.24115 -6.42559,26.458327 10.20535,8.69346 z"
id="path20-5"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 199.10622,-70.089373 v 15.874997 l 11.33929,-0.37797 -2.64583,-18.142857 z"
id="path22-6"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 331.57829,135.39346 30.23809,-92.226199 32.12798,92.226199 z"
id="path10-2"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 392.81043,78.697031 3.77977,44.979179 41.57737,-45.735129 z"
id="path12-9"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 402.63782,21.244651 -12.47322,35.90774 9.44941,14.74107 41.19939,-20.7887 -12.09523,-16.25296 z"
id="path14-1"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 326.6646,-49.436895 34.39583,22.300596 6.04762,-30.994056 z"
id="path16-2"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 351.23305,22.378581 24.19048,-54.806551 30.99405,46.491081 z"
id="path18-7"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 421.53662,-7.1035593 -6.42559,26.4583303 10.20535,8.69346 z"
id="path20-0"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 369.75388,28.048221 v 15.875 l 11.33929,-0.37797 -2.64583,-18.14286 z"
id="path22-9"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 39.89996,238.75616 30.2381,-92.22619 32.12797,92.22619 z"
id="path10-36"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 101.13211,182.05973 3.77976,44.97917 41.57739,-45.73512 z"
id="path12-0"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 110.95949,124.60735 -12.47322,35.90774 9.44941,14.74107 41.19941,-20.78869 -12.09524,-16.25298 z"
id="path14-6"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 32.718413,16.884141 34.39584,22.30059 6.04761,-30.9940503 z"
id="path16-26"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 59.55472,125.74128 83.7452,70.934731 114.73925,117.4258 Z"
id="path18-1"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 129.8583,96.259141 -6.42559,26.458329 10.20535,8.69345 z"
id="path20-8"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 78.07555,131.41092 v 15.875 l 11.33929,-0.37797 -2.64583,-18.14286 z"
id="path22-7"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 175.18194,290.97558 30.23809,-92.22621 32.12798,92.22621 z"
id="path10-3-9"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 236.41408,234.27915 3.77977,44.97918 41.57737,-45.73514 z"
id="path12-6-2"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 170.26825,106.14522 34.39583,22.3006 6.04762,-30.994059 z"
id="path16-5-0"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 194.8367,177.9607 24.19048,-54.80656 30.99405,46.49109 z"
id="path18-3-2"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 265.14027,148.47856 -6.42559,26.45833 10.20535,8.69346 z"
id="path20-5-3"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 213.35753,183.63034 v 15.87499 l 11.33929,-0.37797 -2.64583,-18.14285 z"
id="path22-6-7"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 106.96726,-20.877975 152.70238,-7.6488083 116.79464,86.467239 Z"
id="path2222"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 162.90774,49.425573 324.30357,111.79165 266.47322,27.502966 307.29465,-17.4762 332.61905,6.3362993 352.27381,-7.6488083 320.90177,-40.910724 295.1994,-52.250009 274.03274,-9.9166843 237.74702,46.023799 Z"
id="path2224"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 323.16965,146.56546 -12.85121,111.50299 45.35715,9.82736 17.76489,-57.45236 z"
id="path2226"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 272.89881,284.90474 19.65476,-70.30355 9.44941,3.40177 -16.25298,68.79167 z"
id="path2228"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 238.88095,89.86904 72.57144,25.32441 0.75594,33.26191 z"
id="path2230"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 146.65476,46.023799 8.31548,86.934511 9.07142,4.91371 z"
id="path2234"
inkscape:connector-curvature="0" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 13 KiB