Better polygon drawing.
This commit is contained in:
parent
54fde8bf42
commit
615f3b939c
|
@ -1,248 +0,0 @@
|
|||
<mxfile host="app.diagrams.net" modified="2020-09-09T07:14:46.737Z" agent="5.0 (Macintosh)" etag="dRkj5vYc0Ob2cmZxvQQg" version="13.6.9" type="github">
|
||||
<diagram id="3gZBypMQXWnROILSaoLv" name="Page-1">
|
||||
<mxGraphModel dx="951" dy="539" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0" />
|
||||
<mxCell id="1" parent="0" />
|
||||
<mxCell id="KhT-XE7tMC2H0jqukzKB-9" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="KhT-XE7tMC2H0jqukzKB-6" target="KhT-XE7tMC2H0jqukzKB-10" edge="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="400" y="200" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="KhT-XE7tMC2H0jqukzKB-6" value="drawImage()" style="verticalLabelPosition=middle;verticalAlign=middle;html=1;shape=card;whiteSpace=wrap;size=20;arcSize=12;labelPosition=center;align=center;" parent="1" vertex="1">
|
||||
<mxGeometry x="350" y="50" width="100" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KhT-XE7tMC2H0jqukzKB-26" value="Yes" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;exitPerimeter=0;entryX=-0.01;entryY=0.522;entryDx=0;entryDy=0;entryPerimeter=0;" parent="1" source="KhT-XE7tMC2H0jqukzKB-10" target="4jjFHMcL_OWMd-a0Lr0d-30" edge="1">
|
||||
<mxGeometry x="0.0769" y="15" relative="1" as="geometry">
|
||||
<mxPoint x="520" y="245" as="targetPoint" />
|
||||
<mxPoint as="offset" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="4jjFHMcL_OWMd-a0Lr0d-40" value="No" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="1" source="KhT-XE7tMC2H0jqukzKB-10" target="4jjFHMcL_OWMd-a0Lr0d-31">
|
||||
<mxGeometry x="-0.4118" y="30" relative="1" as="geometry">
|
||||
<mxPoint x="230" y="360" as="targetPoint" />
|
||||
<Array as="points">
|
||||
<mxPoint x="400" y="360" />
|
||||
</Array>
|
||||
<mxPoint as="offset" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="KhT-XE7tMC2H0jqukzKB-10" value="<div>has https:// or http:// <br></div><div>in path</div>" style="strokeWidth=2;html=1;shape=mxgraph.flowchart.decision;whiteSpace=wrap;" parent="1" vertex="1">
|
||||
<mxGeometry x="325" y="170" width="150" height="150" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KhT-XE7tMC2H0jqukzKB-23" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" edge="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="400" y="250" as="sourcePoint" />
|
||||
<mxPoint x="400" y="250" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="4jjFHMcL_OWMd-a0Lr0d-32" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="1" source="4jjFHMcL_OWMd-a0Lr0d-30" target="4jjFHMcL_OWMd-a0Lr0d-31">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="4jjFHMcL_OWMd-a0Lr0d-30" value="downloadFile()" style="verticalLabelPosition=middle;verticalAlign=middle;html=1;shape=card;whiteSpace=wrap;size=20;arcSize=12;labelPosition=center;align=center;" vertex="1" parent="1">
|
||||
<mxGeometry x="530" y="215" width="100" height="57" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="4jjFHMcL_OWMd-a0Lr0d-52" value="<div>1 bit</div>" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="4jjFHMcL_OWMd-a0Lr0d-31" target="4jjFHMcL_OWMd-a0Lr0d-55">
|
||||
<mxGeometry x="-0.7143" y="10" relative="1" as="geometry">
|
||||
<mxPoint x="580" y="480" as="targetPoint" />
|
||||
<Array as="points">
|
||||
<mxPoint x="580" y="450" />
|
||||
<mxPoint x="580" y="450" />
|
||||
</Array>
|
||||
<mxPoint as="offset" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="4jjFHMcL_OWMd-a0Lr0d-53" value="n bit" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="4jjFHMcL_OWMd-a0Lr0d-31" target="4jjFHMcL_OWMd-a0Lr0d-56">
|
||||
<mxGeometry x="-0.8571" y="10" relative="1" as="geometry">
|
||||
<mxPoint x="650" y="480" as="targetPoint" />
|
||||
<Array as="points">
|
||||
<mxPoint x="650" y="360" />
|
||||
<mxPoint x="650" y="590" />
|
||||
</Array>
|
||||
<mxPoint as="offset" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="4jjFHMcL_OWMd-a0Lr0d-31" value="Image depth" style="strokeWidth=2;html=1;shape=mxgraph.flowchart.decision;whiteSpace=wrap;" vertex="1" parent="1">
|
||||
<mxGeometry x="530" y="310" width="100" height="100" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="4jjFHMcL_OWMd-a0Lr0d-58" value="BW" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="4jjFHMcL_OWMd-a0Lr0d-55" target="4jjFHMcL_OWMd-a0Lr0d-57">
|
||||
<mxGeometry x="-0.7838" y="-15" relative="1" as="geometry">
|
||||
<mxPoint as="offset" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="4jjFHMcL_OWMd-a0Lr0d-64" value="Gray" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="1" source="4jjFHMcL_OWMd-a0Lr0d-55" target="4jjFHMcL_OWMd-a0Lr0d-61">
|
||||
<mxGeometry x="-0.5" y="20" relative="1" as="geometry">
|
||||
<mxPoint as="offset" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="4jjFHMcL_OWMd-a0Lr0d-55" value="Screen depth" style="rhombus;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="540" y="475" width="80" height="80" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="4jjFHMcL_OWMd-a0Lr0d-63" value="Gray" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="4jjFHMcL_OWMd-a0Lr0d-56" target="4jjFHMcL_OWMd-a0Lr0d-57">
|
||||
<mxGeometry x="-0.8095" y="-10" relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="500" y="630" />
|
||||
<mxPoint x="500" y="710" />
|
||||
</Array>
|
||||
<mxPoint as="offset" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="4jjFHMcL_OWMd-a0Lr0d-67" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="4jjFHMcL_OWMd-a0Lr0d-56">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="670" y="690" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="4jjFHMcL_OWMd-a0Lr0d-56" value="Screen depth" style="rhombus;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="630" y="590" width="80" height="80" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="4jjFHMcL_OWMd-a0Lr0d-66" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="4jjFHMcL_OWMd-a0Lr0d-57" target="4jjFHMcL_OWMd-a0Lr0d-74">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="430" y="770" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="4jjFHMcL_OWMd-a0Lr0d-57" value="Awesome!" style="verticalLabelPosition=middle;verticalAlign=middle;html=1;shape=card;whiteSpace=wrap;size=20;arcSize=12;labelPosition=center;align=center;" vertex="1" parent="1">
|
||||
<mxGeometry x="380" y="690" width="100" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="4jjFHMcL_OWMd-a0Lr0d-65" value="BW" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0;entryDx=60;entryDy=0;entryPerimeter=0;" edge="1" parent="1" source="4jjFHMcL_OWMd-a0Lr0d-61" target="4jjFHMcL_OWMd-a0Lr0d-57">
|
||||
<mxGeometry x="-0.7538" y="-18" relative="1" as="geometry">
|
||||
<mxPoint as="offset" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="4jjFHMcL_OWMd-a0Lr0d-61" value="Convert color" style="verticalLabelPosition=middle;verticalAlign=middle;html=1;shape=card;whiteSpace=wrap;size=20;arcSize=12;labelPosition=center;align=center;" vertex="1" parent="1">
|
||||
<mxGeometry x="530" y="575" width="100" height="25" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="4jjFHMcL_OWMd-a0Lr0d-97" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="4jjFHMcL_OWMd-a0Lr0d-70" target="4jjFHMcL_OWMd-a0Lr0d-89">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="4jjFHMcL_OWMd-a0Lr0d-70" value="Bad!" style="verticalLabelPosition=middle;verticalAlign=middle;html=1;shape=card;whiteSpace=wrap;size=20;arcSize=12;labelPosition=center;align=center;" vertex="1" parent="1">
|
||||
<mxGeometry x="620" y="690" width="100" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="4jjFHMcL_OWMd-a0Lr0d-76" value="Yes" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" edge="1" parent="1" source="4jjFHMcL_OWMd-a0Lr0d-74" target="4jjFHMcL_OWMd-a0Lr0d-77">
|
||||
<mxGeometry x="-0.3348" y="20" relative="1" as="geometry">
|
||||
<mxPoint x="430.33333333333326" y="880" as="targetPoint" />
|
||||
<mxPoint x="5" y="3" as="offset" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="4jjFHMcL_OWMd-a0Lr0d-79" value="No" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="4jjFHMcL_OWMd-a0Lr0d-74">
|
||||
<mxGeometry x="-0.9091" y="10" relative="1" as="geometry">
|
||||
<mxPoint x="430" y="960" as="targetPoint" />
|
||||
<Array as="points">
|
||||
<mxPoint x="500" y="820" />
|
||||
<mxPoint x="500" y="940" />
|
||||
</Array>
|
||||
<mxPoint as="offset" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="4jjFHMcL_OWMd-a0Lr0d-74" value="Dither" style="rhombus;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="390" y="780" width="80" height="80" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="4jjFHMcL_OWMd-a0Lr0d-80" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="4jjFHMcL_OWMd-a0Lr0d-77" target="4jjFHMcL_OWMd-a0Lr0d-84">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="430.0049999999999" y="960" as="targetPoint" />
|
||||
<Array as="points" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="4jjFHMcL_OWMd-a0Lr0d-77" value="<div>Dither</div>" style="verticalLabelPosition=middle;verticalAlign=middle;html=1;shape=card;whiteSpace=wrap;size=20;arcSize=12;labelPosition=center;align=center;" vertex="1" parent="1">
|
||||
<mxGeometry x="394.84" y="890" width="70.33" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="4jjFHMcL_OWMd-a0Lr0d-82" value="Yes" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" edge="1" parent="1" source="4jjFHMcL_OWMd-a0Lr0d-84" target="4jjFHMcL_OWMd-a0Lr0d-86">
|
||||
<mxGeometry x="-0.3348" y="20" relative="1" as="geometry">
|
||||
<mxPoint x="430.33333333333326" y="1060" as="targetPoint" />
|
||||
<mxPoint x="5" y="3" as="offset" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="4jjFHMcL_OWMd-a0Lr0d-83" value="No" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="4jjFHMcL_OWMd-a0Lr0d-84">
|
||||
<mxGeometry x="-0.9091" y="10" relative="1" as="geometry">
|
||||
<mxPoint x="430" y="1140" as="targetPoint" />
|
||||
<Array as="points">
|
||||
<mxPoint x="500" y="1000" />
|
||||
<mxPoint x="500" y="1120" />
|
||||
</Array>
|
||||
<mxPoint as="offset" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="4jjFHMcL_OWMd-a0Lr0d-84" value="Invert" style="rhombus;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="390" y="960" width="80" height="80" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="4jjFHMcL_OWMd-a0Lr0d-85" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="4jjFHMcL_OWMd-a0Lr0d-86" target="4jjFHMcL_OWMd-a0Lr0d-103">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="430.0049999999999" y="1140" as="targetPoint" />
|
||||
<Array as="points">
|
||||
<mxPoint x="430" y="1200" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="4jjFHMcL_OWMd-a0Lr0d-86" value="Invert" style="verticalLabelPosition=middle;verticalAlign=middle;html=1;shape=card;whiteSpace=wrap;size=20;arcSize=12;labelPosition=center;align=center;" vertex="1" parent="1">
|
||||
<mxGeometry x="394.8399999999999" y="1070" width="70.33" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="4jjFHMcL_OWMd-a0Lr0d-87" value="Yes" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" edge="1" parent="1" source="4jjFHMcL_OWMd-a0Lr0d-89" target="4jjFHMcL_OWMd-a0Lr0d-91">
|
||||
<mxGeometry x="-0.3348" y="20" relative="1" as="geometry">
|
||||
<mxPoint x="670.3333333333333" y="880" as="targetPoint" />
|
||||
<mxPoint x="5" y="3" as="offset" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="4jjFHMcL_OWMd-a0Lr0d-100" value="No" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="1" source="4jjFHMcL_OWMd-a0Lr0d-89" target="4jjFHMcL_OWMd-a0Lr0d-99">
|
||||
<mxGeometry x="-0.8264" y="10" relative="1" as="geometry">
|
||||
<mxPoint as="offset" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="4jjFHMcL_OWMd-a0Lr0d-89" value="Dither" style="rhombus;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="630" y="780" width="80" height="80" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="4jjFHMcL_OWMd-a0Lr0d-90" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="4jjFHMcL_OWMd-a0Lr0d-91" target="4jjFHMcL_OWMd-a0Lr0d-94">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="670.0049999999999" y="960" as="targetPoint" />
|
||||
<Array as="points" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="4jjFHMcL_OWMd-a0Lr0d-91" value="<div>Dither</div>" style="verticalLabelPosition=middle;verticalAlign=middle;html=1;shape=card;whiteSpace=wrap;size=20;arcSize=12;labelPosition=center;align=center;" vertex="1" parent="1">
|
||||
<mxGeometry x="634.8399999999999" y="890" width="70.33" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="4jjFHMcL_OWMd-a0Lr0d-92" value="Yes" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" edge="1" parent="1" source="4jjFHMcL_OWMd-a0Lr0d-94" target="4jjFHMcL_OWMd-a0Lr0d-96">
|
||||
<mxGeometry x="-0.3348" y="20" relative="1" as="geometry">
|
||||
<mxPoint x="670.3333333333333" y="1060" as="targetPoint" />
|
||||
<mxPoint x="5" y="3" as="offset" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="4jjFHMcL_OWMd-a0Lr0d-93" value="No" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="4jjFHMcL_OWMd-a0Lr0d-94">
|
||||
<mxGeometry x="-0.9091" y="10" relative="1" as="geometry">
|
||||
<mxPoint x="670" y="1140" as="targetPoint" />
|
||||
<Array as="points">
|
||||
<mxPoint x="740" y="1000" />
|
||||
<mxPoint x="740" y="1120" />
|
||||
</Array>
|
||||
<mxPoint as="offset" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="4jjFHMcL_OWMd-a0Lr0d-94" value="Invert" style="rhombus;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="630" y="960" width="80" height="80" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="4jjFHMcL_OWMd-a0Lr0d-95" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="4jjFHMcL_OWMd-a0Lr0d-96" target="4jjFHMcL_OWMd-a0Lr0d-103">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="670.0049999999999" y="1140" as="targetPoint" />
|
||||
<Array as="points">
|
||||
<mxPoint x="670" y="1200" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="4jjFHMcL_OWMd-a0Lr0d-96" value="Invert" style="verticalLabelPosition=middle;verticalAlign=middle;html=1;shape=card;whiteSpace=wrap;size=20;arcSize=12;labelPosition=center;align=center;" vertex="1" parent="1">
|
||||
<mxGeometry x="634.8399999999999" y="1070" width="70.33" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="4jjFHMcL_OWMd-a0Lr0d-101" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="4jjFHMcL_OWMd-a0Lr0d-99" target="4jjFHMcL_OWMd-a0Lr0d-94">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="755" y="940" />
|
||||
<mxPoint x="670" y="940" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="4jjFHMcL_OWMd-a0Lr0d-99" value="Threshold" style="verticalLabelPosition=middle;verticalAlign=middle;html=1;shape=card;whiteSpace=wrap;size=20;arcSize=12;labelPosition=center;align=center;" vertex="1" parent="1">
|
||||
<mxGeometry x="719.9999999999999" y="890" width="70.33" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="4jjFHMcL_OWMd-a0Lr0d-103" value="Actual draw" style="ellipse;shape=cloud;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="500" y="1160" width="120" height="80" as="geometry" />
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
|
@ -23,7 +23,6 @@ Inkplate display(INKPLATE_3BIT); // Create object on Inkplate library and set li
|
|||
// Other option is monochrome mode, which is demonstrated in next example
|
||||
// "2-Inkplate_basic_monochrome"
|
||||
|
||||
|
||||
#define DELAY_MS \
|
||||
5000 //Delay in milliseconds between screen refresh. Refreshing e-paper screens more often than 5s is not recommended \
|
||||
//Want to refresh faster? Use partial update! Find example in "3-Inkplate-basic_partial_update"
|
||||
|
|
|
@ -26,7 +26,8 @@ int offset = 800;
|
|||
|
||||
//Variable that keeps count on how much screen has been partially updated
|
||||
int n = 0;
|
||||
void setup() {
|
||||
void setup()
|
||||
{
|
||||
display.begin(); //Init Inkplate library (you should call this function ONLY ONCE)
|
||||
display.clearDisplay(); //Clear frame buffer of display
|
||||
display.display(); //Put clear image on display
|
||||
|
@ -35,18 +36,23 @@ void setup() {
|
|||
display.setTextWrap(false); //Disable text wraping
|
||||
}
|
||||
|
||||
void loop() {
|
||||
void loop()
|
||||
{
|
||||
display.clearDisplay(); //Clear content in frame buffer
|
||||
display.setCursor(offset, 300); //Set new position for text
|
||||
display.print(text); //Write text at new position
|
||||
if(n>9) { //Check if you need to do full refresh or you can do partial update
|
||||
if (n > 9)
|
||||
{ //Check if you need to do full refresh or you can do partial update
|
||||
display.display(); //Do a full refresh
|
||||
n = 0;
|
||||
}else{
|
||||
}
|
||||
else
|
||||
{
|
||||
display.partialUpdate(); //Do partial update
|
||||
n++; //Keep track on how many times screen has been partially updated
|
||||
}
|
||||
offset-=20; //Move text into new position
|
||||
if(offset<0) offset = 800; //Text is scrolled till the end of the screen? Get it back on the start!
|
||||
offset -= 20; //Move text into new position
|
||||
if (offset < 0)
|
||||
offset = 800; //Text is scrolled till the end of the screen? Get it back on the start!
|
||||
delay(500); //Delay between refreshes.
|
||||
}
|
||||
|
|
|
@ -24,14 +24,15 @@
|
|||
#include "DSEG14Classic_Regular20pt7b.h" //Include second font
|
||||
Inkplate display(INKPLATE_1BIT); //Create an object on Inkplate library and also set library into 1-bit mode (Monochrome)
|
||||
|
||||
void setup() {
|
||||
void setup()
|
||||
{
|
||||
display.begin(); //Init Inkplate library (you should call this function ONLY ONCE)
|
||||
display.clearDisplay(); //Clear frame buffer of display
|
||||
display.display(); //Put clear image on display
|
||||
|
||||
display.setFont(&Not_Just_Groovy20pt7b); //Select new font
|
||||
display.setTextSize(2); //Set font scaling to two (font will be 2 times bigger)
|
||||
display.setCursor(0,60); //Set print cursor on X = 0, Y = 60
|
||||
display.setCursor(0, 60); //Set print cursor on X = 0, Y = 60
|
||||
display.println("Inkplate 6"); //Print some text
|
||||
display.setTextSize(1); //Set font scaling to one (font is now original size)
|
||||
display.print("by e-radionica.com"); //Print text
|
||||
|
@ -49,6 +50,7 @@ void setup() {
|
|||
display.display(); //Display everything on display
|
||||
}
|
||||
|
||||
void loop() {
|
||||
void loop()
|
||||
{
|
||||
//Nothing...
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#include "picture2.h"
|
||||
#include "picture3.h"
|
||||
#include "driver/rtc_io.h" //ESP32 library used for deep sleep and RTC wake up pins
|
||||
const uint8_t* pictures[] = {pic1, pic2, pic3}; //This array of pinters holds address of every picture in the memory,
|
||||
const uint8_t *pictures[] = {pic1, pic2, pic3}; //This array of pinters holds address of every picture in the memory,
|
||||
//so we can easly select it by selecting index in array
|
||||
|
||||
#define uS_TO_S_FACTOR 1000000 //Conversion factor for micro seconds to seconds
|
||||
|
@ -31,20 +31,22 @@ RTC_DATA_ATTR int slide = 0;
|
|||
|
||||
Inkplate display(INKPLATE_3BIT); //Create an object on Inkplate library and also set library into 3 Bit mode (Grayscale)
|
||||
|
||||
void setup() {
|
||||
void setup()
|
||||
{
|
||||
display.begin(); //Init Inkplate library (you should call this function ONLY ONCE)
|
||||
display.clearDisplay(); //Clear frame buffer of display
|
||||
display.drawBitmap3Bit(0, 0, pictures[slide], 800, 600); //Display selected picture at location X=0, Y=0. All three pictures have resolution of 800x600 pixels
|
||||
display.display(); //Refresh the screen with new picture
|
||||
slide++; //Update counter for pictures. With this variable, we choose what picture is going to be displayed on screen
|
||||
if (slide > 2) slide = 0; //We do not have more than 3 images, so roll back to zero
|
||||
if (slide > 2)
|
||||
slide = 0; //We do not have more than 3 images, so roll back to zero
|
||||
|
||||
rtc_gpio_isolate(GPIO_NUM_12); //Isolate/disable GPIO12 on ESP32 (only to reduce power consumption in sleep)
|
||||
esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR); //Activate wake-up timer -- wake up after 20s here
|
||||
esp_deep_sleep_start(); //Put ESP32 into deep sleep. Program stops here.
|
||||
}
|
||||
|
||||
void loop() {
|
||||
void loop()
|
||||
{
|
||||
//Nothing! If you use deep sleep, whole program should be in setup() because each time the board restarts, not in a loop()! loop() must be empty!
|
||||
|
||||
}
|
||||
|
|
|
@ -20,7 +20,8 @@
|
|||
//It is in same folder as this sketch. You can even open it (read it) by clicking on symbols.h tab in Arduino IDE
|
||||
Inkplate display(INKPLATE_1BIT); //Create an object on Inkplate library and also set library into 1-bit mode (Monochrome)
|
||||
|
||||
void setup() {
|
||||
void setup()
|
||||
{
|
||||
display.begin(); //Init Inkplate library (you should call this function ONLY ONCE)
|
||||
display.clearDisplay(); //Clear frame buffer of display
|
||||
display.display(); //Put clear image on display
|
||||
|
@ -28,7 +29,8 @@ void setup() {
|
|||
display.setTextColor(BLACK, WHITE); //Set text color to black and background color to white
|
||||
}
|
||||
|
||||
void loop() {
|
||||
void loop()
|
||||
{
|
||||
int temperature;
|
||||
float voltage;
|
||||
|
||||
|
@ -46,5 +48,4 @@ void loop() {
|
|||
display.print('C');
|
||||
display.display(); //Send everything to display (refresh the screen)
|
||||
delay(10000); //Wait 10 seconds before new measurement
|
||||
|
||||
}
|
||||
|
|
|
@ -24,38 +24,48 @@
|
|||
Inkplate display(INKPLATE_1BIT); //Create an object on Inkplate library and also set library into 1 Bit mode (Monochrome)
|
||||
SdFile file; //Create SdFile object used for accessing files on SD card
|
||||
|
||||
void setup() {
|
||||
void setup()
|
||||
{
|
||||
display.begin(); //Init Inkplate library (you should call this function ONLY ONCE)
|
||||
display.clearDisplay(); //Clear frame buffer of display
|
||||
display.display(); //Put clear image on display
|
||||
|
||||
//Init SD card. Display if SD card is init propery or not.
|
||||
if (display.sdCardInit()) {
|
||||
if (display.sdCardInit())
|
||||
{
|
||||
display.println("SD Card ok! Reading data...");
|
||||
display.partialUpdate();
|
||||
|
||||
//Try to load text with max lenght of 200 chars.
|
||||
if (!file.open("/text.txt", O_RDONLY)) { //If it fails to open, send error message to display, otherwise read the file.
|
||||
if (!file.open("/text.txt", O_RDONLY))
|
||||
{ //If it fails to open, send error message to display, otherwise read the file.
|
||||
display.println("File open error");
|
||||
display.display();
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
display.clearDisplay(); //Clear everything that is stored in frame buffer of epaper
|
||||
display.setCursor(0,0); //Set print position at the begining of the screen
|
||||
display.setCursor(0, 0); //Set print position at the begining of the screen
|
||||
char text[201]; //Array where data from SD card is stored (max 200 chars here)
|
||||
int len = file.fileSize(); //Read how big is file that we are opening
|
||||
if(len>200) len = 200; //If it's more than 200 bytes (200 chars), limit to max 200 bytes
|
||||
if (len > 200)
|
||||
len = 200; //If it's more than 200 bytes (200 chars), limit to max 200 bytes
|
||||
file.read(text, len); //Read data from file and save it in text array
|
||||
text[len] = 0; //Put null terminating char at the and of data
|
||||
display.print(text); //Print data/text
|
||||
display.display(); //Do a full refresh of display
|
||||
}
|
||||
} else { //If card init was not successful, display error on screen and stop the program (using infinite loop)
|
||||
}
|
||||
else
|
||||
{ //If card init was not successful, display error on screen and stop the program (using infinite loop)
|
||||
display.println("SD Card error!");
|
||||
display.partialUpdate();
|
||||
while (true);
|
||||
while (true)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
void loop()
|
||||
{
|
||||
//Nothing...
|
||||
}
|
||||
|
|
|
@ -27,17 +27,20 @@ Adafruit_BME680 bme; //Create an object on Adafruit BME680 librar
|
|||
//(with no arguments sent to constructor, that means we are using I2C communication for BME680 sensor)
|
||||
|
||||
int n = 0; //Variable that keep track on how many times screen has been partially updated
|
||||
void setup() {
|
||||
void setup()
|
||||
{
|
||||
display.begin(); //Init Inkplate library (you should call this function ONLY ONCE)
|
||||
display.clearDisplay(); //Clear frame buffer of display
|
||||
display.display(); //Put clear image on display
|
||||
display.setTextSize(2); //Set text scaling to two (text will be two times bigger than normal)
|
||||
|
||||
if (!bme.begin(0x76)) { //Init. BME680 library. e-radionica.com BME680 sensor board uses 0x76 I2C address for sensor
|
||||
if (!bme.begin(0x76))
|
||||
{ //Init. BME680 library. e-radionica.com BME680 sensor board uses 0x76 I2C address for sensor
|
||||
display.println("Sensor init failed!");
|
||||
display.println("Check sensor wiring/connection!");
|
||||
display.partialUpdate();
|
||||
while (1);
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
|
||||
//Set up oversampling and filter initialization for the sensor
|
||||
|
@ -48,13 +51,17 @@ void setup() {
|
|||
bme.setGasHeater(320, 150); // 320*C for 150 ms
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if (!bme.performReading()) { //If sending command to start reading data fails, send error message to display
|
||||
void loop()
|
||||
{
|
||||
if (!bme.performReading())
|
||||
{ //If sending command to start reading data fails, send error message to display
|
||||
display.clearDisplay();
|
||||
display.setCursor(0, 0);
|
||||
display.print("Failed to read data from sensor");
|
||||
display.partialUpdate();
|
||||
} else { //Otherwise, clear frame buffer of epaper display
|
||||
}
|
||||
else
|
||||
{ //Otherwise, clear frame buffer of epaper display
|
||||
display.clearDisplay(); //Print out new data
|
||||
display.setCursor(0, 0);
|
||||
display.print("Air temperature: ");
|
||||
|
@ -73,10 +80,13 @@ void loop() {
|
|||
display.print(bme.gas_resistance / 1000.0);
|
||||
display.println(" kOhms");
|
||||
|
||||
if(n>20) { //If display has been partially updated more than 20 times, do a full refresh, otherwise, perform a partial update.
|
||||
if (n > 20)
|
||||
{ //If display has been partially updated more than 20 times, do a full refresh, otherwise, perform a partial update.
|
||||
display.display();
|
||||
n = 0;
|
||||
}else{
|
||||
}
|
||||
else
|
||||
{
|
||||
display.partialUpdate();
|
||||
n++;
|
||||
}
|
||||
|
|
|
@ -29,14 +29,16 @@
|
|||
|
||||
Inkplate display(INKPLATE_1BIT); //Create an object on Inkplate library and also set library into 1-bit mode (Monochrome)
|
||||
|
||||
void setup() {
|
||||
void setup()
|
||||
{
|
||||
display.begin(); //Init Inkplate library (you should call this function ONLY ONCE)
|
||||
pinModeMCP(LED_PIN, OUTPUT); //Set pin 15 (or GPB7) to output. On that pin, we sholud connect LED with current limiting resistor
|
||||
display.pinModeMCP(LED_PIN, OUTPUT); //Set pin 15 (or GPB7) to output. On that pin, we sholud connect LED with current limiting resistor
|
||||
}
|
||||
|
||||
void loop() {
|
||||
digitalWriteMCP(LED_PIN, LOW); //Set output to low (LED does not light up)
|
||||
void loop()
|
||||
{
|
||||
display.digitalWriteMCP(LED_PIN, LOW); //Set output to low (LED does not light up)
|
||||
delay(1000); //Wait for one second
|
||||
digitalWriteMCP(LED_PIN, HIGH); //Set output to high (LED lights up)
|
||||
display.digitalWriteMCP(LED_PIN, HIGH); //Set output to high (LED lights up)
|
||||
delay(1000); //Wait for one second
|
||||
}
|
||||
|
|
|
@ -33,7 +33,8 @@ WebServer server(80); //Create Web server on port 80 (HTTP port nu
|
|||
IPAddress serverIP;
|
||||
String txt;
|
||||
|
||||
void setup() {
|
||||
void setup()
|
||||
{
|
||||
display.begin(); //Init Inkplate library (you should call this function ONLY ONCE)
|
||||
display.clearDisplay(); //Clear frame buffer of display
|
||||
display.display(); //Put clear image on display
|
||||
|
@ -53,25 +54,30 @@ void setup() {
|
|||
updatePaper();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
void loop()
|
||||
{
|
||||
server.handleClient(); //You have to constantly read if there is any new client connected to web server
|
||||
}
|
||||
|
||||
void updateHTML() { //This function will send response to client and send HTML code of our web page
|
||||
void updateHTML()
|
||||
{ //This function will send response to client and send HTML code of our web page
|
||||
server.send(200, "text/html", s);
|
||||
}
|
||||
|
||||
void handleRoot() { //This function will send response to client if client open a root (homepage) of our web page
|
||||
void handleRoot()
|
||||
{ //This function will send response to client if client open a root (homepage) of our web page
|
||||
updateHTML();
|
||||
}
|
||||
|
||||
void handleString() { //This function will send response to client, send HTML code of web page, get the text from argument sent in web page address and refresh screen with new text
|
||||
void handleString()
|
||||
{ //This function will send response to client, send HTML code of web page, get the text from argument sent in web page address and refresh screen with new text
|
||||
txt = server.arg(0);
|
||||
updateHTML();
|
||||
updatePaper();
|
||||
}
|
||||
|
||||
void updatePaper() { //This function updates screen with new data (text)
|
||||
void updatePaper()
|
||||
{ //This function updates screen with new data (text)
|
||||
display.clearDisplay(); //Clear everything from epaper frame buffer
|
||||
display.setCursor(20, 40); //Print out instruction on how to connect to Inkplate WiFi and how to open a web page
|
||||
display.print("Connect to ");
|
||||
|
|
|
@ -21,10 +21,11 @@
|
|||
#include "WiFi.h" //Include library for WiFi
|
||||
Inkplate display(INKPLATE_1BIT); //Create an object on Inkplate library and also set library into 1 Bit mode (Monochrome)
|
||||
|
||||
const char* ssid = ""; //Your WiFi SSID
|
||||
const char* password = ""; //Your WiFi password
|
||||
const char *ssid = ""; //Your WiFi SSID
|
||||
const char *password = ""; //Your WiFi password
|
||||
|
||||
void setup() {
|
||||
void setup()
|
||||
{
|
||||
display.begin(); //Init Inkplate library (you should call this function ONLY ONCE)
|
||||
display.clearDisplay(); //Clear frame buffer of display
|
||||
display.display(); //Put clear image on display
|
||||
|
@ -35,7 +36,8 @@ void setup() {
|
|||
//Connect to the WiFi network.
|
||||
WiFi.mode(WIFI_MODE_STA);
|
||||
WiFi.begin(ssid, password);
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
while (WiFi.status() != WL_CONNECTED)
|
||||
{
|
||||
delay(500);
|
||||
display.print(".");
|
||||
display.partialUpdate();
|
||||
|
@ -50,7 +52,8 @@ void setup() {
|
|||
//certain softwares.
|
||||
//Forth parameter will dither the image.
|
||||
//Photo taken by: Roberto Fernandez
|
||||
if (!display.drawBitmapFromWeb("https://varipass.org/neowise_mono.bmp", 0, 0, false, true)) {
|
||||
if (!display.drawBitmapFromWeb("https://varipass.org/neowise_mono.bmp", 0, 0, false, true))
|
||||
{
|
||||
//If is something failed (wrong filename or wrong bitmap format), write error message on the screen.
|
||||
//REMEMBER! You can only use Windows Bitmap file with color depth of 1, 4, 8 or 24 bits with no compression!
|
||||
display.println("Image open error");
|
||||
|
@ -70,11 +73,14 @@ void setup() {
|
|||
|
||||
//Check response code.
|
||||
int httpCode = http.GET();
|
||||
if (httpCode == 200) {
|
||||
if (httpCode == 200)
|
||||
{
|
||||
//Get the response length and make sure it is not 0.
|
||||
int32_t len = http.getSize();
|
||||
if (len > 0) {
|
||||
if (!display.drawBitmapFromWeb(http.getStreamPtr(), 0, 0, len)) {
|
||||
if (len > 0)
|
||||
{
|
||||
if (!display.drawBitmapFromWeb(http.getStreamPtr(), 0, 0, len))
|
||||
{
|
||||
//If is something failed (wrong filename or wrong bitmap format), write error message on the screen.
|
||||
//REMEMBER! You can only use Windows Bitmap file with color depth of 1, 4, 8 or 24 bits with no compression!
|
||||
display.println("Image open error");
|
||||
|
@ -82,12 +88,14 @@ void setup() {
|
|||
}
|
||||
display.display();
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
display.println("Invalid response length");
|
||||
display.display();
|
||||
}
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
display.println("HTTP error");
|
||||
display.display();
|
||||
}
|
||||
|
@ -97,6 +105,7 @@ void setup() {
|
|||
WiFi.mode(WIFI_OFF);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
void loop()
|
||||
{
|
||||
//Nothing...
|
||||
}
|
||||
|
|
|
@ -22,8 +22,8 @@
|
|||
|
||||
#include "Inkplate.h" //Include Inkplate library to the sketch
|
||||
#include "SdFat.h" //Include library for SD card
|
||||
Inkplate display(
|
||||
INKPLATE_1BIT); // Create an object on Inkplate library and also set library into 1 Bit mode (Monochrome)
|
||||
|
||||
Inkplate display(INKPLATE_1BIT); // Create an object on Inkplate library and also set library into 1 Bit mode (Monochrome)
|
||||
SdFile file; // Create SdFile object used for accessing files on SD card
|
||||
|
||||
void setup()
|
||||
|
|
|
@ -55,10 +55,9 @@ Inkplate display(INKPLATE_1BIT);
|
|||
Network network;
|
||||
|
||||
// Contants used for drawing icons
|
||||
char abbrs[32][16] ={ "sn", "sl", "h", "t", "hr", "lr", "s", "hc", "lc", "c" };
|
||||
const uint8_t *logos[16] ={ icon_sn, icon_sl, icon_h, icon_t, icon_hr, icon_lr, icon_s, icon_hc, icon_lc, icon_c };
|
||||
const uint8_t *s_logos[16] ={ icon_s_sn, icon_s_sl, icon_s_h, icon_s_t, icon_s_hr, icon_s_lr, icon_s_s, icon_s_hc, icon_s_lc, icon_s_c };
|
||||
|
||||
char abbrs[32][16] = {"sn", "sl", "h", "t", "hr", "lr", "s", "hc", "lc", "c"};
|
||||
const uint8_t *logos[16] = {icon_sn, icon_sl, icon_h, icon_t, icon_hr, icon_lr, icon_s, icon_hc, icon_lc, icon_c};
|
||||
const uint8_t *s_logos[16] = {icon_s_sn, icon_s_sl, icon_s_h, icon_s_t, icon_s_hr, icon_s_lr, icon_s_s, icon_s_hc, icon_s_lc, icon_s_c};
|
||||
|
||||
char abbr1[16];
|
||||
char abbr2[16];
|
||||
|
@ -66,7 +65,7 @@ char abbr3[16];
|
|||
char abbr4[16];
|
||||
|
||||
// Variables for storing temperature
|
||||
char temps[8][4] ={
|
||||
char temps[8][4] = {
|
||||
"0F",
|
||||
"0F",
|
||||
"0F",
|
||||
|
@ -74,7 +73,7 @@ char temps[8][4] ={
|
|||
};
|
||||
|
||||
// Variables for storing days of the week
|
||||
char days[8][4] ={
|
||||
char days[8][4] = {
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
|
@ -160,8 +159,6 @@ void loop()
|
|||
else
|
||||
display.partialUpdate();
|
||||
|
||||
|
||||
|
||||
// Go to sleep before checking again
|
||||
esp_sleep_enable_timer_wakeup(1000L * DELAY_MS);
|
||||
(void)esp_light_sleep_start();
|
||||
|
|
|
@ -99,23 +99,6 @@ void Shapes::fillElipse(int rx, int ry, int xc, int yc, int c)
|
|||
}
|
||||
}
|
||||
|
||||
void Shapes::fillPolygon(int *x, int *y, int n, int color)
|
||||
{
|
||||
int tx[100], ty[100];
|
||||
triangulate.triangulate(x, y, n, tx, ty);
|
||||
|
||||
for (int i = 0; i < n - 2; ++i)
|
||||
{
|
||||
fillTriangle(tx[i * 3 + 0], ty[i * 3 + 0], tx[i * 3 + 1], ty[i * 3 + 1], tx[i * 3 + 2], ty[i * 3 + 2], color);
|
||||
}
|
||||
}
|
||||
|
||||
void Shapes::drawPolygon(int *x, int *y, int n, int color)
|
||||
{
|
||||
for (int i = 0; i < n; ++i)
|
||||
drawLine(x[i], y[i], x[(i + 1) % n], y[(i + 1) % n], color);
|
||||
}
|
||||
|
||||
void Shapes::drawThickLine(int x1, int y1, int x2, int y2, int color, float thickness)
|
||||
{
|
||||
float deg = atan2f((float)(y2 - y1), (float)(x2 - x1));
|
||||
|
|
|
@ -3,11 +3,13 @@
|
|||
|
||||
#include "../libs/Adafruit-GFX-Library/Adafruit_GFX.h"
|
||||
#include "Arduino.h"
|
||||
#include "Triangulate.h"
|
||||
|
||||
#define maxVer 100
|
||||
#define maxHt 600
|
||||
|
||||
class Shapes : virtual public Adafruit_GFX
|
||||
{
|
||||
public:
|
||||
public:
|
||||
Shapes(int16_t w, int16_t h) : Adafruit_GFX(w, h){};
|
||||
|
||||
virtual void drawPixel(int16_t x, int16_t y, uint16_t color) = 0;
|
||||
|
@ -22,8 +24,27 @@ class Shapes : virtual public Adafruit_GFX
|
|||
void drawThickLine(int x1, int y1, int x2, int y2, int color, float thickness);
|
||||
void drawGradientLine(int x1, int y1, int x2, int y2, int color1, int color2, float thickness = -1);
|
||||
|
||||
private:
|
||||
Triangulate triangulate;
|
||||
private:
|
||||
struct EdgeBucket
|
||||
{
|
||||
int ymax;
|
||||
float xofymin;
|
||||
float slopeinverse;
|
||||
};
|
||||
|
||||
struct edgeTableTuple
|
||||
{
|
||||
int countEdgeBucket;
|
||||
EdgeBucket buckets[maxVer];
|
||||
};
|
||||
|
||||
void initedgeTable();
|
||||
void insertionSort(edgeTableTuple *ett);
|
||||
void storeEdgeInTuple(edgeTableTuple *receiver, int ym, int xm, float slopInv);
|
||||
void storeEdgeInTable(int x1, int y1, int x2, int y2);
|
||||
void removeEdgeByYmax(edgeTableTuple *tup, int yy);
|
||||
void updatexbyslopeinv(edgeTableTuple *tup);
|
||||
void scanlineFill(uint8_t c);
|
||||
|
||||
virtual void startWrite(void) = 0;
|
||||
virtual void writePixel(int16_t x, int16_t y, uint16_t color) = 0;
|
||||
|
@ -32,6 +53,8 @@ class Shapes : virtual public Adafruit_GFX
|
|||
virtual void writeFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color) = 0;
|
||||
virtual void writeLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color) = 0;
|
||||
virtual void endWrite(void) = 0;
|
||||
|
||||
edgeTableTuple *edgeTable, activeEdgeTuple;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,231 @@
|
|||
#include "Shapes.h"
|
||||
|
||||
void Shapes::initedgeTable()
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < maxHt; i++)
|
||||
edgeTable[i].countEdgeBucket = 0;
|
||||
activeEdgeTuple.countEdgeBucket = 0;
|
||||
}
|
||||
|
||||
void Shapes::insertionSort(edgeTableTuple *ett)
|
||||
{
|
||||
int i, j;
|
||||
EdgeBucket temp;
|
||||
|
||||
for (i = 1; i < ett->countEdgeBucket; i++)
|
||||
{
|
||||
temp.ymax = ett->buckets[i].ymax;
|
||||
temp.xofymin = ett->buckets[i].xofymin;
|
||||
temp.slopeinverse = ett->buckets[i].slopeinverse;
|
||||
j = i - 1;
|
||||
|
||||
while ((temp.xofymin < ett->buckets[j].xofymin) && (j >= 0))
|
||||
{
|
||||
ett->buckets[j + 1].ymax = ett->buckets[j].ymax;
|
||||
ett->buckets[j + 1].xofymin = ett->buckets[j].xofymin;
|
||||
ett->buckets[j + 1].slopeinverse = ett->buckets[j].slopeinverse;
|
||||
j = j - 1;
|
||||
}
|
||||
ett->buckets[j + 1].ymax = temp.ymax;
|
||||
ett->buckets[j + 1].xofymin = temp.xofymin;
|
||||
ett->buckets[j + 1].slopeinverse = temp.slopeinverse;
|
||||
}
|
||||
}
|
||||
|
||||
void Shapes::storeEdgeInTuple(edgeTableTuple *receiver, int ym, int xm, float slopInv)
|
||||
{
|
||||
(receiver->buckets[(receiver)->countEdgeBucket]).ymax = ym;
|
||||
(receiver->buckets[(receiver)->countEdgeBucket]).xofymin = (float)xm;
|
||||
(receiver->buckets[(receiver)->countEdgeBucket]).slopeinverse = slopInv;
|
||||
|
||||
insertionSort(receiver);
|
||||
|
||||
(receiver->countEdgeBucket)++;
|
||||
}
|
||||
|
||||
void Shapes::storeEdgeInTable(int x1, int y1, int x2, int y2)
|
||||
{
|
||||
float m, minv;
|
||||
int ymaxTS, xwithyminTS, scanline; //ts stands for to store
|
||||
|
||||
if (x2 == x1)
|
||||
{
|
||||
minv = 0.000000;
|
||||
}
|
||||
else
|
||||
{
|
||||
m = ((float)(y2 - y1)) / ((float)(x2 - x1));
|
||||
|
||||
if (y2 == y1)
|
||||
return;
|
||||
|
||||
minv = (float)1.0 / m;
|
||||
}
|
||||
|
||||
if (y1 > y2)
|
||||
{
|
||||
scanline = y2;
|
||||
ymaxTS = y1;
|
||||
xwithyminTS = x2;
|
||||
}
|
||||
else
|
||||
{
|
||||
scanline = y1;
|
||||
ymaxTS = y2;
|
||||
xwithyminTS = x1;
|
||||
}
|
||||
storeEdgeInTuple(&edgeTable[scanline], ymaxTS, xwithyminTS, minv);
|
||||
}
|
||||
|
||||
void Shapes::removeEdgeByYmax(edgeTableTuple *tup, int yy)
|
||||
{
|
||||
int i, j;
|
||||
for (i = 0; i < tup->countEdgeBucket; i++)
|
||||
{
|
||||
if (tup->buckets[i].ymax == yy)
|
||||
{
|
||||
for (j = i; j < tup->countEdgeBucket - 1; j++)
|
||||
{
|
||||
tup->buckets[j].ymax = tup->buckets[j + 1].ymax;
|
||||
tup->buckets[j].xofymin = tup->buckets[j + 1].xofymin;
|
||||
tup->buckets[j].slopeinverse = tup->buckets[j + 1].slopeinverse;
|
||||
}
|
||||
tup->countEdgeBucket--;
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Shapes::updatexbyslopeinv(edgeTableTuple *tup)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < tup->countEdgeBucket; i++)
|
||||
{
|
||||
(tup->buckets[i]).xofymin = (tup->buckets[i]).xofymin + (tup->buckets[i]).slopeinverse;
|
||||
}
|
||||
}
|
||||
|
||||
void Shapes::scanlineFill(uint8_t c)
|
||||
{
|
||||
int i, j, x1, ymax1, x2, ymax2, FillFlag = 0, coordCount;
|
||||
|
||||
for (i = 0; i < maxHt; i++)
|
||||
{
|
||||
for (j = 0; j < edgeTable[i].countEdgeBucket; j++)
|
||||
storeEdgeInTuple(&activeEdgeTuple, edgeTable[i].buckets[j].ymax, edgeTable[i].buckets[j].xofymin,
|
||||
edgeTable[i].buckets[j].slopeinverse);
|
||||
|
||||
removeEdgeByYmax(&activeEdgeTuple, i);
|
||||
insertionSort(&activeEdgeTuple);
|
||||
|
||||
j = 0;
|
||||
FillFlag = 0;
|
||||
coordCount = 0;
|
||||
x1 = 0;
|
||||
x2 = 0;
|
||||
ymax1 = 0;
|
||||
ymax2 = 0;
|
||||
while (j < activeEdgeTuple.countEdgeBucket)
|
||||
{
|
||||
if (coordCount % 2 == 0)
|
||||
{
|
||||
x1 = (int)(activeEdgeTuple.buckets[j].xofymin);
|
||||
ymax1 = activeEdgeTuple.buckets[j].ymax;
|
||||
if (x1 == x2)
|
||||
{
|
||||
if (((x1 == ymax1) && (x2 != ymax2)) || ((x1 != ymax1) && (x2 == ymax2)))
|
||||
{
|
||||
x2 = x1;
|
||||
ymax2 = ymax1;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
coordCount++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
coordCount++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
x2 = (int)activeEdgeTuple.buckets[j].xofymin;
|
||||
ymax2 = activeEdgeTuple.buckets[j].ymax;
|
||||
|
||||
FillFlag = 0;
|
||||
if (x1 == x2)
|
||||
{
|
||||
if (((x1 == ymax1) && (x2 != ymax2)) || ((x1 != ymax1) && (x2 == ymax2)))
|
||||
{
|
||||
x1 = x2;
|
||||
ymax1 = ymax2;
|
||||
}
|
||||
else
|
||||
{
|
||||
coordCount++;
|
||||
FillFlag = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
coordCount++;
|
||||
FillFlag = 1;
|
||||
}
|
||||
|
||||
if (FillFlag)
|
||||
{
|
||||
Serial.println(x1);
|
||||
Serial.println(x2);
|
||||
Serial.println();
|
||||
drawLine(x1, i, x2, i, c);
|
||||
}
|
||||
}
|
||||
|
||||
j++;
|
||||
}
|
||||
updatexbyslopeinv(&activeEdgeTuple);
|
||||
}
|
||||
}
|
||||
|
||||
void Shapes::drawPolygon(int *x, int *y, int n, int color)
|
||||
{
|
||||
for (int i = 0; i < n; ++i)
|
||||
drawLine(x[i], y[i], x[(i + 1) % n], y[(i + 1) % n], color);
|
||||
}
|
||||
|
||||
void Shapes::fillPolygon(int *x, int *y, int n, int color)
|
||||
{
|
||||
edgeTable = (edgeTableTuple *)ps_malloc(maxHt * sizeof(edgeTableTuple));
|
||||
initedgeTable();
|
||||
|
||||
int count = 0, x1, y1, x2, y2;
|
||||
|
||||
for (int i = 0; i < n + 1; ++i)
|
||||
{
|
||||
count++;
|
||||
if (count > 2)
|
||||
{
|
||||
x1 = x2;
|
||||
y1 = y2;
|
||||
count = 2;
|
||||
}
|
||||
if (count == 1)
|
||||
{
|
||||
x1 = x[i % n];
|
||||
y1 = y[i % n];
|
||||
}
|
||||
else
|
||||
{
|
||||
x2 = x[i % n];
|
||||
y2 = y[i % n];
|
||||
drawLine(x1, y1, x2, y2, color);
|
||||
storeEdgeInTable(x1, y1, x2, y2);
|
||||
}
|
||||
}
|
||||
scanlineFill(color);
|
||||
free(edgeTable);
|
||||
}
|
|
@ -1,143 +0,0 @@
|
|||
#include "Triangulate.h"
|
||||
#include "Arduino.h"
|
||||
#include "math.h"
|
||||
|
||||
float Triangulate::area(int x1, int y1, int x2, int y2, int x3, int y3)
|
||||
{
|
||||
return fabs((float)((x1 * (y2 - y3) + x2 * (y3 - y1) + x3 * (y1 - y2))) / 2.0);
|
||||
}
|
||||
|
||||
bool Triangulate::isInside(int x1, int y1, int x2, int y2, int x3, int y3, int x, int y)
|
||||
{
|
||||
float A = area(x1, y1, x2, y2, x3, y3);
|
||||
float A1 = area(x, y, x2, y2, x3, y3);
|
||||
float A2 = area(x1, y1, x, y, x3, y3);
|
||||
float A3 = area(x1, y1, x2, y2, x, y);
|
||||
return fabs(-A + A1 + A2 + A3) < 1e-3;
|
||||
}
|
||||
|
||||
void Triangulate::preProcess(int *x, int *y, int n)
|
||||
{
|
||||
for (int i = 0; i < n; ++i)
|
||||
{
|
||||
int prev = (i - 1 + n) % n;
|
||||
int next = (i + 1 + n) % n;
|
||||
float deg = atan2(y[prev] - y[i], x[prev] - x[i]) - atan2(y[next] - y[i], x[next] - x[i]);
|
||||
if (deg < 0.0)
|
||||
deg += 2 * M_PI;
|
||||
innerAngle[i] = deg;
|
||||
}
|
||||
}
|
||||
|
||||
void Triangulate::updateVertex(int p, int *x, int *y, int n)
|
||||
{
|
||||
int prev = (p - 1 + n) % n;
|
||||
int next = (p + 1 + n) % n;
|
||||
float deg = atan2(y[prev] - y[p], x[prev] - x[p]) - atan2(y[next] - y[p], x[next] - x[p]);
|
||||
if (deg < 0.0)
|
||||
deg += 2 * M_PI;
|
||||
innerAngle[p] = deg;
|
||||
bool f = 0;
|
||||
for (int j = 0; j < n; ++j)
|
||||
{
|
||||
if (prev != j && p != j && next != j && innerAngle[p] > M_PI &&
|
||||
isInside(x[prev], y[prev], x[p], y[p], x[next], y[next], x[j], y[j]))
|
||||
f = 1;
|
||||
}
|
||||
earTip[p] = !f;
|
||||
}
|
||||
|
||||
bool Triangulate::isConvex(int *x, int *y, int n)
|
||||
{
|
||||
for (int i = 0; i < n; ++i)
|
||||
if (innerAngle[i] > M_PI)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void Triangulate::trivialTriangles(int *x, int *y, int n)
|
||||
{
|
||||
for (int i = 0; i < n - 2; ++i)
|
||||
{
|
||||
tx[tc] = x[0];
|
||||
ty[tc] = y[0];
|
||||
++tc;
|
||||
tx[tc] = x[i + 1];
|
||||
ty[tc] = y[i + 1];
|
||||
++tc;
|
||||
tx[tc] = x[i + 2];
|
||||
ty[tc] = y[i + 2];
|
||||
++tc;
|
||||
}
|
||||
}
|
||||
|
||||
void Triangulate::findEars(int *x, int *y, int n)
|
||||
{
|
||||
for (int i = 0; i < n; ++i)
|
||||
{
|
||||
if (innerAngle[i] > M_PI)
|
||||
continue;
|
||||
int prev = (i - 1 + n) % n;
|
||||
int next = (i + 1 + n) % n;
|
||||
bool f = 0;
|
||||
for (int j = 0; j < n; ++j)
|
||||
{
|
||||
if (prev != j && i != j && next != j && innerAngle[i] > M_PI &&
|
||||
isInside(x[prev], y[prev], x[i], y[i], x[next], y[next], x[j], y[j]))
|
||||
f = 1;
|
||||
}
|
||||
earTip[i] = !f;
|
||||
}
|
||||
}
|
||||
|
||||
int Triangulate::smallestEar(int *x, int *y, int n)
|
||||
{
|
||||
int mn = 0;
|
||||
for (int i = 1; i < n; ++i)
|
||||
if (earTip[i] && innerAngle[i] < innerAngle[mn])
|
||||
mn = i;
|
||||
return mn;
|
||||
}
|
||||
|
||||
void Triangulate::nonTrivialTriangles(int *x, int *y, int n)
|
||||
{
|
||||
findEars(x, y, n);
|
||||
int initialN = n;
|
||||
while (tc / 3 < initialN - 2)
|
||||
{
|
||||
int pos = smallestEar(x, y, n);
|
||||
int prev = (pos - 1 + n) % n;
|
||||
int next = (pos + 1 + n) % n;
|
||||
tx[tc] = x[prev];
|
||||
ty[tc] = y[prev];
|
||||
++tc;
|
||||
tx[tc] = x[pos];
|
||||
ty[tc] = y[pos];
|
||||
++tc;
|
||||
tx[tc] = x[next];
|
||||
ty[tc] = y[next];
|
||||
++tc;
|
||||
for (int i = pos; i < n - 1; i++)
|
||||
{
|
||||
x[i] = x[i + 1];
|
||||
y[i] = y[i + 1];
|
||||
innerAngle[i] = innerAngle[i + 1];
|
||||
earTip[i] = earTip[i + 1];
|
||||
}
|
||||
--n;
|
||||
updateVertex(prev, x, y, n);
|
||||
updateVertex(prev + 1, x, y, n);
|
||||
}
|
||||
}
|
||||
|
||||
void Triangulate::triangulate(int *x, int *y, int n, int *_tx, int *_ty)
|
||||
{
|
||||
tc = 0;
|
||||
preProcess(x, y, n);
|
||||
if (isConvex(x, y, n))
|
||||
trivialTriangles(x, y, n);
|
||||
else
|
||||
nonTrivialTriangles(x, y, n);
|
||||
memcpy(_tx, tx, 100);
|
||||
memcpy(_ty, ty, 100);
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
#ifndef TRIANGULATE_H
|
||||
#define TRIANGULATE_H
|
||||
|
||||
#include "Arduino.h"
|
||||
|
||||
class Triangulate
|
||||
{
|
||||
private:
|
||||
int tx[100];
|
||||
int ty[100];
|
||||
int tc = 0;
|
||||
|
||||
float innerAngle[100];
|
||||
bool earTip[100];
|
||||
|
||||
float area(int x1, int y1, int x2, int y2, int x3, int y3);
|
||||
bool isInside(int x1, int y1, int x2, int y2, int x3, int y3, int x, int y);
|
||||
void preProcess(int *x, int *y, int n);
|
||||
void updateVertex(int p, int *x, int *y, int n);
|
||||
bool isConvex(int *x, int *y, int n);
|
||||
void trivialTriangles(int *x, int *y, int n);
|
||||
void findEars(int *x, int *y, int n);
|
||||
int smallestEar(int *x, int *y, int n);
|
||||
void nonTrivialTriangles(int *x, int *y, int n);
|
||||
|
||||
public:
|
||||
void triangulate(int *x, int *y, int n, int *_tx, int *_ty);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1 @@
|
|||
#include "Inkplate.h"
|
|
@ -0,0 +1 @@
|
|||
#include "Inkplate.h"
|
|
@ -1,6 +1,8 @@
|
|||
#include "Inkplate.h"
|
||||
#include "SdFat.h"
|
||||
|
||||
const int n = 10;
|
||||
|
||||
Inkplate display(INKPLATE_1BIT);
|
||||
|
||||
void setup()
|
||||
|
@ -11,20 +13,42 @@ void setup()
|
|||
|
||||
display.joinAP("e-radionica.com", "croduino");
|
||||
|
||||
Serial.println();
|
||||
Serial.println("aaaa");
|
||||
delay(500);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
display.clearDisplay();
|
||||
display.display();
|
||||
|
||||
if (display.sdCardInit())
|
||||
// Code block for generating random points and sorting them in a counter
|
||||
// clockwise direction.
|
||||
int xt[n];
|
||||
int yt[n];
|
||||
|
||||
for (int i = 0; i < n; ++i)
|
||||
{
|
||||
Serial.println(display.drawJpegFromSd("Lenna.jpg", 0, 0, 1, 0));
|
||||
xt[i] = random(100, 700);
|
||||
yt[i] = random(100, 500);
|
||||
}
|
||||
display.display();
|
||||
|
||||
int k;
|
||||
for (int i = 0; i < n - 1; ++i)
|
||||
|
||||
for (int j = i + 1; j < n; ++j)
|
||||
if (atan2(yt[j] - 300, xt[j] - 400) < atan2(yt[i] - 300, xt[i] - 400))
|
||||
{
|
||||
k = xt[i], xt[i] = xt[j], xt[j] = k;
|
||||
k = yt[i], yt[i] = yt[j], yt[j] = k;
|
||||
}
|
||||
|
||||
display.clearDisplay();
|
||||
display.drawPolygon(xt, yt, n, 1);
|
||||
display.display();
|
||||
delay(5000);
|
||||
|
||||
display.clearDisplay();
|
||||
display.fillPolygon(xt, yt, n, 1);
|
||||
display.display();
|
||||
delay(5000);
|
||||
}
|
Loading…
Reference in New Issue