initial rewrite
@ -0,0 +1,65 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Licensed as CC0 Public Domain Dedication, see https://creativecommons.org/publicdomain/zero/1.0/. -->
|
||||
|
||||
<svg
|
||||
xmlns:ns="http://creativecommons.org/"
|
||||
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"
|
||||
version="1.1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
width="306.19147"
|
||||
height="186.78011"
|
||||
viewBox="0 0 306.19147 186.78011"
|
||||
xml:space="preserve"
|
||||
id="svg11"
|
||||
sodipodi:docname="robotbody_longerleft.svg"
|
||||
inkscape:version="0.92.2 (unknown)"><metadata
|
||||
id="metadata17"><rdf:RDF><ns:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></ns:Work><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><defs
|
||||
id="defs15" /><sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1016"
|
||||
id="namedview13"
|
||||
showgrid="false"
|
||||
inkscape:zoom="1.5742187"
|
||||
inkscape:cx="193.78259"
|
||||
inkscape:cy="72.49728"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg11"
|
||||
showguides="true"
|
||||
inkscape:guide-bbox="true"
|
||||
inkscape:snap-center="true"
|
||||
inkscape:snap-page="true"
|
||||
inkscape:snap-global="false"><sodipodi:guide
|
||||
position="87.480965,95.186771"
|
||||
orientation="1,0"
|
||||
id="guide863"
|
||||
inkscape:locked="false" /><sodipodi:guide
|
||||
position="87.480965,95.186771"
|
||||
orientation="0,1"
|
||||
id="guide867"
|
||||
inkscape:locked="false" /></sodipodi:namedview><path
|
||||
id="robotbody"
|
||||
d="m 21.840805,32.282261 c -29.4070742,38.075324 -29.2031002,89.304329 1.126302,124.879399 28.308167,33.20432 96.216923,41.60047 129.034143,9.08347 20.97597,3.07228 22.33436,4.02195 28.5988,-5.90513 5.06112,-8.02021 -4.86652,-25.70583 -4.67439,-28.06416 2.47109,-30.33143 1.21949,-67.484605 -2.03551,-83.758545 -0.8545,-4.27227 140.86445,3.74803 131.89259,-6.66691 C 295.93739,30.421398 158.23428,27.099346 155.90436,24.175764 133.57052,-3.8490539 58.313014,-14.940787 21.840805,32.282261 Z"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="sscssssss"
|
||||
style="stroke-width:0.99999988" /></svg>
|
After Width: | Height: | Size: 2.8 KiB |
@ -0,0 +1,65 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Licensed as CC0 Public Domain Dedication, see https://creativecommons.org/publicdomain/zero/1.0/. -->
|
||||
|
||||
<svg
|
||||
xmlns:ns="http://creativecommons.org/"
|
||||
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"
|
||||
version="1.1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
width="316.32892"
|
||||
height="186.78011"
|
||||
viewBox="0 0 316.32892 186.78011"
|
||||
xml:space="preserve"
|
||||
id="svg11"
|
||||
sodipodi:docname="robotbody_longerleft_mediumright.svg"
|
||||
inkscape:version="0.92.2 (unknown)"><metadata
|
||||
id="metadata17"><rdf:RDF><ns:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></ns:Work><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><defs
|
||||
id="defs15" /><sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1016"
|
||||
id="namedview13"
|
||||
showgrid="false"
|
||||
inkscape:zoom="1.5742187"
|
||||
inkscape:cx="193.78259"
|
||||
inkscape:cy="72.49728"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg11"
|
||||
showguides="true"
|
||||
inkscape:guide-bbox="true"
|
||||
inkscape:snap-center="true"
|
||||
inkscape:snap-page="true"
|
||||
inkscape:snap-global="false"><sodipodi:guide
|
||||
position="87.480965,95.186771"
|
||||
orientation="1,0"
|
||||
id="guide863"
|
||||
inkscape:locked="false" /><sodipodi:guide
|
||||
position="87.480965,95.186771"
|
||||
orientation="0,1"
|
||||
id="guide867"
|
||||
inkscape:locked="false" /></sodipodi:namedview><path
|
||||
id="robotbody"
|
||||
d="m 21.840805,32.282261 c -29.4070742,38.075324 -29.2031002,89.304329 1.126302,124.879399 28.308167,33.20432 96.216923,41.60047 129.034143,9.08347 20.97597,3.07228 40.7562,3.38671 47.02064,-6.54037 5.06112,-8.02021 -23.28836,-25.07059 -23.09623,-27.42892 2.47109,-30.33143 1.21949,-67.484605 -2.03551,-83.758545 -0.8545,-4.27227 151.02822,1.84232 142.05636,-8.572618 C 306.10116,28.515691 158.23428,27.099346 155.90436,24.175764 133.57052,-3.8490539 58.313014,-14.940787 21.840805,32.282261 Z"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="sscssssss"
|
||||
style="stroke-width:0.99999988" /></svg>
|
After Width: | Height: | Size: 2.8 KiB |
@ -0,0 +1,65 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Licensed as CC0 Public Domain Dedication, see https://creativecommons.org/publicdomain/zero/1.0/. -->
|
||||
|
||||
<svg
|
||||
xmlns:ns="http://creativecommons.org/"
|
||||
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"
|
||||
version="1.1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
width="239.8282"
|
||||
height="186.78011"
|
||||
viewBox="0 0 239.8282 186.78011"
|
||||
xml:space="preserve"
|
||||
id="svg11"
|
||||
sodipodi:docname="robotbody_longleft.svg"
|
||||
inkscape:version="0.92.2 (unknown)"><metadata
|
||||
id="metadata17"><rdf:RDF><ns:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></ns:Work><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs15" /><sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1016"
|
||||
id="namedview13"
|
||||
showgrid="false"
|
||||
inkscape:zoom="1.5742187"
|
||||
inkscape:cx="193.78259"
|
||||
inkscape:cy="72.49728"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg11"
|
||||
showguides="true"
|
||||
inkscape:guide-bbox="true"
|
||||
inkscape:snap-center="true"
|
||||
inkscape:snap-page="true"
|
||||
inkscape:snap-global="false"><sodipodi:guide
|
||||
position="87.480965,95.186771"
|
||||
orientation="1,0"
|
||||
id="guide863"
|
||||
inkscape:locked="false" /><sodipodi:guide
|
||||
position="87.480965,95.186771"
|
||||
orientation="0,1"
|
||||
id="guide867"
|
||||
inkscape:locked="false" /></sodipodi:namedview><path
|
||||
id="robotbody"
|
||||
d="m 21.840805,32.282261 c -29.4070742,38.075324 -29.2031002,89.304329 1.126302,124.879399 28.308167,33.20432 96.216923,41.60047 129.034143,9.08347 20.97597,3.07228 22.33436,4.02195 28.5988,-5.90513 5.06112,-8.02021 -4.86652,-25.70583 -4.67439,-28.06416 2.47109,-30.33143 1.21949,-67.484605 -2.03551,-83.758545 -0.8545,-4.27227 74.1647,3.74803 65.19284,-6.66691 C 229.23764,30.421398 158.23428,27.099346 155.90436,24.175764 133.57052,-3.8490539 58.313014,-14.940787 21.840805,32.282261 Z"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="sscssssss"
|
||||
style="stroke-width:0.99999988" /></svg>
|
After Width: | Height: | Size: 2.8 KiB |
@ -0,0 +1,65 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Licensed as CC0 Public Domain Dedication, see https://creativecommons.org/publicdomain/zero/1.0/. -->
|
||||
|
||||
<svg
|
||||
xmlns:ns="http://creativecommons.org/"
|
||||
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"
|
||||
version="1.1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
width="239.19885"
|
||||
height="186.78011"
|
||||
viewBox="0 0 239.19885 186.78011"
|
||||
xml:space="preserve"
|
||||
id="svg11"
|
||||
sodipodi:docname="robotbody_longleft_mediumright.svg"
|
||||
inkscape:version="0.92.2 (unknown)"><metadata
|
||||
id="metadata17"><rdf:RDF><ns:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></ns:Work><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs15" /><sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1016"
|
||||
id="namedview13"
|
||||
showgrid="false"
|
||||
inkscape:zoom="1.5742187"
|
||||
inkscape:cx="193.78259"
|
||||
inkscape:cy="72.49728"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg11"
|
||||
showguides="true"
|
||||
inkscape:guide-bbox="true"
|
||||
inkscape:snap-center="true"
|
||||
inkscape:snap-page="true"
|
||||
inkscape:snap-global="false"><sodipodi:guide
|
||||
position="87.480964,95.18677"
|
||||
orientation="1,0"
|
||||
id="guide863"
|
||||
inkscape:locked="false" /><sodipodi:guide
|
||||
position="87.480964,95.18677"
|
||||
orientation="0,1"
|
||||
id="guide867"
|
||||
inkscape:locked="false" /></sodipodi:namedview><path
|
||||
id="robotbody"
|
||||
d="m 21.840805,32.282261 c -29.4070742,38.075324 -29.2031002,89.304329 1.126302,124.879399 28.308167,33.20432 96.216923,41.60047 129.034143,9.08347 20.97597,3.07228 40.7562,3.38671 47.02064,-6.54037 5.06112,-8.02021 -23.28836,-25.07059 -23.09623,-27.42892 2.47109,-30.33143 1.21949,-67.484605 -2.03551,-83.758545 -0.8545,-4.27227 73.52946,-1.96909 64.5576,-12.384033 C 228.6024,24.704276 158.23428,27.099346 155.90436,24.175764 133.57052,-3.8490539 58.313014,-14.940787 21.840805,32.282261 Z"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="sscssssss"
|
||||
style="stroke-width:0.99999988" /></svg>
|
After Width: | Height: | Size: 2.8 KiB |
@ -0,0 +1,147 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Licensed as CC0 Public Domain Dedication, see https://creativecommons.org/publicdomain/zero/1.0/. -->
|
||||
|
||||
<svg
|
||||
xmlns:ns="http://creativecommons.org/"
|
||||
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"
|
||||
version="1.1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
width="186.78011"
|
||||
height="239.8282"
|
||||
viewBox="0 0 186.7801 239.82821"
|
||||
xml:space="preserve"
|
||||
id="svg11"
|
||||
sodipodi:docname="robotbody_longleft_rabbit.svg"
|
||||
inkscape:version="0.92.2 (unknown)"><metadata
|
||||
id="metadata17"><rdf:RDF><ns:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></ns:Work><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs15"><inkscape:path-effect
|
||||
effect="powerstroke"
|
||||
id="path-effect254"
|
||||
is_visible="true"
|
||||
offset_points="0,0.5"
|
||||
sort_points="true"
|
||||
interpolator_type="CubicBezierJohan"
|
||||
interpolator_beta="0.2"
|
||||
start_linecap_type="zerowidth"
|
||||
linejoin_type="extrp_arc"
|
||||
miter_limit="4"
|
||||
end_linecap_type="zerowidth" /><inkscape:path-effect
|
||||
effect="powerstroke"
|
||||
id="path-effect25"
|
||||
is_visible="true"
|
||||
offset_points="3,0.5"
|
||||
sort_points="true"
|
||||
interpolator_type="CubicBezierJohan"
|
||||
interpolator_beta="0.2"
|
||||
start_linecap_type="zerowidth"
|
||||
linejoin_type="extrp_arc"
|
||||
miter_limit="4"
|
||||
end_linecap_type="zerowidth" /><inkscape:path-effect
|
||||
effect="powerstroke"
|
||||
id="path-effect254-3"
|
||||
is_visible="true"
|
||||
offset_points="0,0.5"
|
||||
sort_points="true"
|
||||
interpolator_type="CubicBezierJohan"
|
||||
interpolator_beta="0.2"
|
||||
start_linecap_type="zerowidth"
|
||||
linejoin_type="extrp_arc"
|
||||
miter_limit="4"
|
||||
end_linecap_type="zerowidth" /></defs><sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1016"
|
||||
id="namedview13"
|
||||
showgrid="true"
|
||||
inkscape:zoom="1.1131407"
|
||||
inkscape:cx="-110.31088"
|
||||
inkscape:cy="158.83002"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg11"
|
||||
showguides="true"
|
||||
inkscape:guide-bbox="true"
|
||||
inkscape:snap-center="true"
|
||||
inkscape:snap-page="true"
|
||||
inkscape:snap-global="false"><sodipodi:guide
|
||||
position="89.835902,94.776877"
|
||||
orientation="0,1"
|
||||
id="guide867"
|
||||
inkscape:locked="false" /><inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid17" /></sodipodi:namedview><path
|
||||
id="robotbody"
|
||||
d="m 32.361665,218.1462 c 38.075324,29.40707 89.304325,29.2031 124.879395,-1.12631 33.20432,-28.30816 41.60047,-96.21692 9.08347,-129.034138 3.07228,-20.97597 4.02195,-22.33436 -5.90513,-28.5988 -8.02021,-5.06112 -25.70583,4.86652 -28.06416,4.67439 -30.33143,-2.47109 -67.484601,-1.21949 -83.758541,2.03551 -4.27227,0.8545 3.74803,-74.1646999 -6.66691,-65.19283985 C 30.500802,10.749362 27.17875,81.752722 24.255168,84.082642 -3.7696494,106.41648 -14.861383,181.67399 32.361665,218.1462 Z"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="sscssssss"
|
||||
style="stroke-width:0.99999988" /><path
|
||||
style="fill:#000000;fill-rule:nonzero;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 95.124644,167.33654 c 6.249246,0 16.791976,0 28.678396,0 -3.42704,2.30174 -8.60423,5.77896 -13.40834,9.0056 -6.21057,-4.10993 -11.750517,-7.77606 -14.994123,-9.92257 C 86.237314,160.35566 58.747523,142.1639 49.584259,136.09998 Z M 49.032393,136.93392 c 9.163263,6.06391 36.653054,24.25567 45.816318,30.31959 3.291923,2.17847 8.949109,5.92219 15.272109,10.10653 l 0.27798,0.18396 0.27673,-0.18586 c 4.88158,-3.27867 10.16593,-6.82786 15.04751,-10.10653 l 1.36244,-0.91507 h -1.64122 c -12.553,0 -23.78418,0 -30.319616,0 z"
|
||||
id="path23"
|
||||
inkscape:connector-curvature="0"
|
||||
inkscape:path-effect="#path-effect25"
|
||||
inkscape:original-d="m 95.124644,166.83654 h 30.319616 l -15.04751,10.10653 z" /><circle
|
||||
style="fill:#ffffff"
|
||||
id="path31"
|
||||
cx="114.10249"
|
||||
cy="114.61942"
|
||||
r="4.8286796" /><circle
|
||||
style="fill:#ffffff"
|
||||
id="path31-3"
|
||||
cx="64.355865"
|
||||
cy="114.95629"
|
||||
r="4.8286796" /><path
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="M 88.836131,156.72999 V 169.7562 Z"
|
||||
id="path48"
|
||||
inkscape:connector-curvature="0" /><path
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 43.91818,156.28081 v 17.29341 H 61.88536 V 154.93327 H 43.469 v 1.34754 z"
|
||||
id="path60"
|
||||
inkscape:connector-curvature="0" /><path
|
||||
style="fill:#ffffff;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 73.82141,145.13271 30,-0.22312 -15.162041,12.27813 z"
|
||||
id="path27"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccc" /><rect
|
||||
style="fill:#ffffff;stroke-width:1.553774"
|
||||
id="rect81"
|
||||
width="1.0844152"
|
||||
height="14.149155"
|
||||
x="87.989937"
|
||||
y="156.28081" /><path
|
||||
style="fill:#ffffff;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 88.836131,170.42997 9.432769,8.53441 15.49669,-9.20818 -15.49669,8.98359 z"
|
||||
id="path91"
|
||||
inkscape:connector-curvature="0" /><path
|
||||
style="fill:#ffffff;fill-rule:nonzero;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 88.56847,170.11108 c 0,0 -0.460602,-0.19454 -0.460602,-0.19454 -1.097812,2.59925 -3.173212,5.69885 -7.130345,7.65121 -2.915718,1.43854 -6.462603,2.02817 -10.134523,1.51988 -3.670134,-0.50805 -7.018082,-2.05238 -9.574048,-4.30369 -3.479573,-3.06484 -4.833237,-6.79321 -5.256314,-9.75475 0.421762,2.95233 1.689623,6.71395 5.123891,9.90118 2.525356,2.3437 5.881966,4.02058 9.630593,4.65147 3.746208,0.63048 7.448089,0.14174 10.555612,-1.28956 4.23834,-1.95215 6.535016,-5.21337 7.706338,-7.98666 0,0 -0.460602,-0.19454 -0.460602,-0.19454 z"
|
||||
id="path252"
|
||||
inkscape:connector-curvature="0"
|
||||
inkscape:path-effect="#path-effect254"
|
||||
inkscape:original-d="m 88.56847,170.11108 c -6.309095,14.93779 -30.208051,11.35258 -32.555832,-5.08189" /><path
|
||||
style="fill:#ffffff;fill-rule:nonzero;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 88.639962,170.16354 c 0,0 -0.460602,0.19454 -0.460602,0.19454 1.171322,2.77329 3.467997,6.03451 7.706337,7.98666 3.107522,1.4313 6.809403,1.92004 10.555603,1.28956 3.74863,-0.63089 7.10524,-2.30777 9.6306,-4.65147 3.43427,-3.18723 4.70213,-6.94885 5.12389,-9.90118 -0.42308,2.96154 -1.77674,6.68991 -5.25631,9.75475 -2.55597,2.25131 -5.90392,3.79564 -9.57405,4.30369 -3.67192,0.50829 -7.218805,-0.0813 -10.134523,-1.51988 -3.957132,-1.95236 -6.032531,-5.05196 -7.130343,-7.65121 0,0 -0.460602,0.19454 -0.460602,0.19454 z"
|
||||
id="path252-5"
|
||||
inkscape:connector-curvature="0"
|
||||
inkscape:path-effect="#path-effect254-3"
|
||||
inkscape:original-d="m 88.639962,170.16354 c 6.309093,14.93779 30.208048,11.35258 32.555828,-5.08189" /></svg>
|
After Width: | Height: | Size: 7.7 KiB |
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.8 KiB |
@ -0,0 +1,174 @@
|
||||
|
||||
// Description of robot(s), and attached sensor(s) used by InstantiateRobot()
|
||||
class Sensor {
|
||||
constructor(id, props) {
|
||||
Object.assign(this, {
|
||||
id,
|
||||
parent: null,
|
||||
lookAngle:0,
|
||||
attachRadius: simInfo.robotSize,
|
||||
value: null,
|
||||
valueStr: "<uninit>",
|
||||
minVal: 0,
|
||||
maxVal: 50
|
||||
}, props)
|
||||
this.info = this
|
||||
this.setAngle(this.attachAngle)
|
||||
}
|
||||
setAngle(attachAngle) {
|
||||
this.attachAngle = attachAngle
|
||||
Object.assign(this, Vec2.fromPolar(Vec2.zero, this.attachRadius, this.attachAngle))
|
||||
}
|
||||
plotSensor(context, x = this.x, y = this.y) {
|
||||
context.beginPath();
|
||||
context.arc(x, y, this.getWidth()/2, 0, 2*Math.PI);
|
||||
context.closePath();
|
||||
context.fillStyle = 'black';
|
||||
context.strokeStyle = this.color ? convrgb(this.color) : 'black';
|
||||
context.fill();
|
||||
context.stroke();
|
||||
}
|
||||
onDragging(sensor, event) {
|
||||
const {x, y} = sim.bay.transformMouse(event.mouse),
|
||||
mAngle = Math.atan2(y, x),
|
||||
mRadius = Math.sqrt(x*x + y*y);
|
||||
this.attachRadius = mRadius
|
||||
this.setAngle(mAngle)
|
||||
sim.bay.repaint()
|
||||
}
|
||||
getWidth() { return 2 }
|
||||
getHeight() { return 2 }
|
||||
mouseHit(x, y) {
|
||||
const mouse = sim.bay.transformMouse({x,y})
|
||||
return Vec2.distLess(this, mouse, this.getWidth()/2 + 1)
|
||||
}
|
||||
};
|
||||
class DistanceSensor extends Sensor {
|
||||
rayCast() {
|
||||
/* Distance sensor simulation based on ray casting. Called from sensor
|
||||
* object, returns nothing, updates a new reading into this.value.
|
||||
*
|
||||
* Idea: Cast a ray with a certain length from the sensor, and check
|
||||
* via collision detection if objects intersect with the ray.
|
||||
* To determine distance, run a Binary search on ray length.
|
||||
* Note: Sensor ray needs to ignore robot (parts), or start outside of it.
|
||||
* The latter is easy with the current circular shape of the robots.
|
||||
* Note: Order of tests are optimized by starting with max ray length, and
|
||||
* then only testing the maximal number of initially resulting objects.
|
||||
* Note: The sensor's "ray" could have any other (convex) shape;
|
||||
* currently it's just a very thin rectangle.
|
||||
*/
|
||||
|
||||
var bodies = Matter.Composite.allBodies(sim.engine.world);
|
||||
if (this.filter) bodies = bodies.filter(this.filter)
|
||||
|
||||
const robotAngle = this.parent.body.angle,
|
||||
rayAngle = robotAngle + this.attachAngle + this.lookAngle;
|
||||
|
||||
const rPos = this.parent.body.position,
|
||||
rSize = this.attachRadius,
|
||||
startPoint = Vec2.fromPolar(rPos, this.attachRadius, robotAngle+this.attachAngle)
|
||||
|
||||
function getEndpoint(rayLength) {
|
||||
return Vec2.fromPolar(startPoint, rayLength, rayAngle)
|
||||
};
|
||||
|
||||
function sensorRay(bodies, rayLength) {
|
||||
// Cast ray of supplied length and return the bodies that collide with it.
|
||||
const rayWidth = 1e-100,
|
||||
ray = Vec2.avg(startPoint, getEndpoint(rayLength)),
|
||||
rayRect = Matter.Bodies.rectangle(ray.x, ray.y, rayLength, rayWidth,
|
||||
{isSensor: true, isStatic: true,
|
||||
angle: rayAngle, role: 'sensor'});
|
||||
|
||||
return bodies.filter(body => {
|
||||
// coarse check on body boundaries, to increase performance:
|
||||
return Matter.Bounds.overlaps(body.bounds, rayRect.bounds) &&
|
||||
body.parts.some((part, pp) => {
|
||||
// skip the first part, if it's not the only one
|
||||
if (pp == 0 && body.parts.length > 1) return false
|
||||
// finer, more costly check on actual geometry:
|
||||
if (Matter.Bounds.overlaps(part.bounds, rayRect.bounds)) {
|
||||
const collision = Matter.SAT.collides(part, rayRect);
|
||||
if (collision.collided) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
};
|
||||
|
||||
// call 1x with full length, and check all bodies in the world;
|
||||
// in subsequent calls, only check the bodies resulting here
|
||||
var rayLength = this.maxVal;
|
||||
bodies = sensorRay(bodies, rayLength);
|
||||
function binarySearch(lo, hi, cond) {
|
||||
let x = hi
|
||||
while (lo < x) {
|
||||
if (cond(x)) {
|
||||
hi = x
|
||||
} else {
|
||||
lo = x
|
||||
}
|
||||
x = Math.floor(lo + (hi-lo)/2)
|
||||
}
|
||||
return x
|
||||
}
|
||||
// if some collided, search for maximal ray length without collisions
|
||||
if (bodies.length > 0) {
|
||||
rayLength = binarySearch(0, rayLength, len => sensorRay(bodies, len).length > 0)
|
||||
}
|
||||
// increase length to (barely) touch closest body (if any)
|
||||
rayLength += 1;
|
||||
bodies = sensorRay(bodies, rayLength);
|
||||
return [bodies, rayLength, startPoint, getEndpoint(rayLength)]
|
||||
}
|
||||
sense() {
|
||||
const context = document.getElementById('arenaLemming').getContext('2d');
|
||||
const [bodies, rayLength, startPoint, endPoint] = this.rayCast()
|
||||
if (simInfo.debugSensors) { // if invisible, check order of object drawing
|
||||
// draw the resulting ray
|
||||
context.strokeStyle = convrgb(this.parent.info.color)
|
||||
context.lineWidth = 0.5;
|
||||
drawVertices(context, [startPoint, endPoint])
|
||||
// mark all objects's lines intersecting with the ray
|
||||
bodies.forEach(({vertices}) => drawVertices(context, vertices))
|
||||
}
|
||||
let rl
|
||||
|
||||
// indicate if the sensor exceeded its maximum length by returning infinity
|
||||
if (rayLength > this.maxVal) {
|
||||
rl = Infinity;
|
||||
}
|
||||
else {
|
||||
rl = Math.floor(rayLength + gaussNoise(3));
|
||||
rl = Matter.Common.clamp(rl, this.minVal, this.maxVal);
|
||||
}
|
||||
|
||||
this.value = rl;
|
||||
this.valueStr = padnumber(this.value, 2);
|
||||
}
|
||||
}
|
||||
function clamp(x, min, max) {
|
||||
return x < min ? min : x > max ? max : x
|
||||
}
|
||||
class ColorSensor extends DistanceSensor {
|
||||
sense() {
|
||||
const [bodies, rayLength] = this.rayCast()
|
||||
let color
|
||||
if (bodies.length) {
|
||||
color = bodies[0].color.map(x => clamp(x + gaussNoise(), 0, 255))
|
||||
} else {
|
||||
color = [255,255,255]
|
||||
}
|
||||
this.value = color
|
||||
this.valueStr = `</span><span style="color: ${convrgb(color)}">` +
|
||||
color.map(x => format(x)).join(', ')
|
||||
}
|
||||
}
|
||||
class Gyroscope extends Sensor {
|
||||
sense() {
|
||||
this.value = (this.parent.body.angle * (180/Math.PI) + gaussNoise()) % 360
|
||||
this.valueStr = format(this.value) + '°'
|
||||
}
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
"use strict"
|
||||
const Vec2 = {
|
||||
add({x:x1, y:y1}, {x:x2, y:y2}) {
|
||||
return Object.freeze({x:x1+x2, y:y1+y2})
|
||||
},
|
||||
avg({x:x1, y:y1}, {x:x2, y:y2}) {
|
||||
return Object.freeze({x:(x1+x2)/2, y:(y1+y2)/2})
|
||||
},
|
||||
fromPolar({x,y}, radius, angle) {
|
||||
return Object.freeze({x: x + radius * Math.cos(angle),
|
||||
y: y + radius * Math.sin(angle)})
|
||||
},
|
||||
sub({x:x1, y:y1}, {x:x2, y:y2}) {
|
||||
return Object.freeze({x:x1-x2, y: y1-y2})
|
||||
},
|
||||
distLess(a, b, radius) {
|
||||
const {x, y} = Vec2.sub(a, b)
|
||||
return ((x*x) + (y*y)) < (radius * radius)
|
||||
},
|
||||
zero: Object.freeze({x:0, y:0})
|
||||
};
|
||||
|
||||
function drawVertices(context, vertices, draw=true, close=true) {
|
||||
if (draw) context.beginPath();
|
||||
context.moveTo(vertices[0].x, vertices[0].y);
|
||||
vertices.slice(1).forEach(({x, y}) =>
|
||||
context.lineTo(x, y))
|
||||
if (close) context.lineTo(vertices[0].x, vertices[0].y);
|
||||
if (draw) context.stroke();
|
||||
}
|
||||
|
||||
function convrgb(values) {
|
||||
return 'rgb(' + values.map(x=>x|0).join(', ') + ')';
|
||||
};
|
||||
|
||||
// apply mild noise on the sensor reading, and clamp between valid values
|
||||
function gaussNoise(sigma=1) {
|
||||
const x0 = 1.0 - Math.random();
|
||||
const x1 = 1.0 - Math.random();
|
||||
return sigma * Math.sqrt(-2 * Math.log(x0)) * Math.cos(2 * Math.PI * x1);
|
||||
};
|