Better polygon drawing.

This commit is contained in:
nitko12 2020-09-14 12:07:34 +02:00
parent 54fde8bf42
commit 615f3b939c
21 changed files with 566 additions and 680 deletions

View File

@ -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="&lt;div&gt;has https:// or http:// &lt;br&gt;&lt;/div&gt;&lt;div&gt;in path&lt;/div&gt;" 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="&lt;div&gt;1 bit&lt;/div&gt;" 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="&lt;div&gt;Dither&lt;/div&gt;" 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="&lt;div&gt;Dither&lt;/div&gt;" 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>

View File

@ -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 // Other option is monochrome mode, which is demonstrated in next example
// "2-Inkplate_basic_monochrome" // "2-Inkplate_basic_monochrome"
#define DELAY_MS \ #define DELAY_MS \
5000 //Delay in milliseconds between screen refresh. Refreshing e-paper screens more often than 5s is not recommended \ 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" //Want to refresh faster? Use partial update! Find example in "3-Inkplate-basic_partial_update"

View File

@ -26,7 +26,8 @@ int offset = 800;
//Variable that keeps count on how much screen has been partially updated //Variable that keeps count on how much screen has been partially updated
int n = 0; int n = 0;
void setup() { void setup()
{
display.begin(); //Init Inkplate library (you should call this function ONLY ONCE) display.begin(); //Init Inkplate library (you should call this function ONLY ONCE)
display.clearDisplay(); //Clear frame buffer of display display.clearDisplay(); //Clear frame buffer of display
display.display(); //Put clear image on display display.display(); //Put clear image on display
@ -35,18 +36,23 @@ void setup() {
display.setTextWrap(false); //Disable text wraping display.setTextWrap(false); //Disable text wraping
} }
void loop() { void loop()
{
display.clearDisplay(); //Clear content in frame buffer display.clearDisplay(); //Clear content in frame buffer
display.setCursor(offset, 300); //Set new position for text display.setCursor(offset, 300); //Set new position for text
display.print(text); //Write text at new position 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 display.display(); //Do a full refresh
n = 0; n = 0;
}else{ }
else
{
display.partialUpdate(); //Do partial update display.partialUpdate(); //Do partial update
n++; //Keep track on how many times screen has been partially updated n++; //Keep track on how many times screen has been partially updated
} }
offset-=20; //Move text into new position 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! 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. delay(500); //Delay between refreshes.
} }

View File

@ -24,14 +24,15 @@
#include "DSEG14Classic_Regular20pt7b.h" //Include second font #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) 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.begin(); //Init Inkplate library (you should call this function ONLY ONCE)
display.clearDisplay(); //Clear frame buffer of display display.clearDisplay(); //Clear frame buffer of display
display.display(); //Put clear image on display display.display(); //Put clear image on display
display.setFont(&Not_Just_Groovy20pt7b); //Select new font display.setFont(&Not_Just_Groovy20pt7b); //Select new font
display.setTextSize(2); //Set font scaling to two (font will be 2 times bigger) 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.println("Inkplate 6"); //Print some text
display.setTextSize(1); //Set font scaling to one (font is now original size) display.setTextSize(1); //Set font scaling to one (font is now original size)
display.print("by e-radionica.com"); //Print text display.print("by e-radionica.com"); //Print text
@ -49,6 +50,7 @@ void setup() {
display.display(); //Display everything on display display.display(); //Display everything on display
} }
void loop() { void loop()
{
//Nothing... //Nothing...
} }

View File

@ -22,7 +22,7 @@
#include "picture2.h" #include "picture2.h"
#include "picture3.h" #include "picture3.h"
#include "driver/rtc_io.h" //ESP32 library used for deep sleep and RTC wake up pins #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 //so we can easly select it by selecting index in array
#define uS_TO_S_FACTOR 1000000 //Conversion factor for micro seconds to seconds #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) 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.begin(); //Init Inkplate library (you should call this function ONLY ONCE)
display.clearDisplay(); //Clear frame buffer of display 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.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 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 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) 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_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. 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! //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!
} }

View File

@ -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 //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) 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.begin(); //Init Inkplate library (you should call this function ONLY ONCE)
display.clearDisplay(); //Clear frame buffer of display display.clearDisplay(); //Clear frame buffer of display
display.display(); //Put clear image on 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 display.setTextColor(BLACK, WHITE); //Set text color to black and background color to white
} }
void loop() { void loop()
{
int temperature; int temperature;
float voltage; float voltage;
@ -46,5 +48,4 @@ void loop() {
display.print('C'); display.print('C');
display.display(); //Send everything to display (refresh the screen) display.display(); //Send everything to display (refresh the screen)
delay(10000); //Wait 10 seconds before new measurement delay(10000); //Wait 10 seconds before new measurement
} }

View File

@ -24,38 +24,48 @@
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 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.begin(); //Init Inkplate library (you should call this function ONLY ONCE)
display.clearDisplay(); //Clear frame buffer of display display.clearDisplay(); //Clear frame buffer of display
display.display(); //Put clear image on display display.display(); //Put clear image on display
//Init SD card. Display if SD card is init propery or not. //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.println("SD Card ok! Reading data...");
display.partialUpdate(); display.partialUpdate();
//Try to load text with max lenght of 200 chars. //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.println("File open error");
display.display(); display.display();
} else { }
else
{
display.clearDisplay(); //Clear everything that is stored in frame buffer of epaper 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) 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 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 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 text[len] = 0; //Put null terminating char at the and of data
display.print(text); //Print data/text display.print(text); //Print data/text
display.display(); //Do a full refresh of display 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.println("SD Card error!");
display.partialUpdate(); display.partialUpdate();
while (true); while (true)
;
} }
} }
void loop() { void loop()
{
//Nothing... //Nothing...
} }

View File

@ -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) //(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 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.begin(); //Init Inkplate library (you should call this function ONLY ONCE)
display.clearDisplay(); //Clear frame buffer of display display.clearDisplay(); //Clear frame buffer of display
display.display(); //Put clear image on display display.display(); //Put clear image on display
display.setTextSize(2); //Set text scaling to two (text will be two times bigger than normal) 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("Sensor init failed!");
display.println("Check sensor wiring/connection!"); display.println("Check sensor wiring/connection!");
display.partialUpdate(); display.partialUpdate();
while (1); while (1)
;
} }
//Set up oversampling and filter initialization for the sensor //Set up oversampling and filter initialization for the sensor
@ -48,13 +51,17 @@ void setup() {
bme.setGasHeater(320, 150); // 320*C for 150 ms bme.setGasHeater(320, 150); // 320*C for 150 ms
} }
void loop() { void loop()
if (!bme.performReading()) { //If sending command to start reading data fails, send error message to display {
if (!bme.performReading())
{ //If sending command to start reading data fails, send error message to display
display.clearDisplay(); display.clearDisplay();
display.setCursor(0, 0); display.setCursor(0, 0);
display.print("Failed to read data from sensor"); display.print("Failed to read data from sensor");
display.partialUpdate(); 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.clearDisplay(); //Print out new data
display.setCursor(0, 0); display.setCursor(0, 0);
display.print("Air temperature: "); display.print("Air temperature: ");
@ -73,10 +80,13 @@ void loop() {
display.print(bme.gas_resistance / 1000.0); display.print(bme.gas_resistance / 1000.0);
display.println(" kOhms"); 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(); display.display();
n = 0; n = 0;
}else{ }
else
{
display.partialUpdate(); display.partialUpdate();
n++; n++;
} }

View File

@ -29,14 +29,16 @@
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)
void setup() { void setup()
{
display.begin(); //Init Inkplate library (you should call this function ONLY ONCE) 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() { void loop()
digitalWriteMCP(LED_PIN, LOW); //Set output to low (LED does not light up) {
display.digitalWriteMCP(LED_PIN, LOW); //Set output to low (LED does not light up)
delay(1000); //Wait for one second 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 delay(1000); //Wait for one second
} }

View File

@ -33,7 +33,8 @@ WebServer server(80); //Create Web server on port 80 (HTTP port nu
IPAddress serverIP; IPAddress serverIP;
String txt; String txt;
void setup() { void setup()
{
display.begin(); //Init Inkplate library (you should call this function ONLY ONCE) display.begin(); //Init Inkplate library (you should call this function ONLY ONCE)
display.clearDisplay(); //Clear frame buffer of display display.clearDisplay(); //Clear frame buffer of display
display.display(); //Put clear image on display display.display(); //Put clear image on display
@ -53,25 +54,30 @@ void setup() {
updatePaper(); updatePaper();
} }
void loop() { void loop()
{
server.handleClient(); //You have to constantly read if there is any new client connected to web server 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); 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(); 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); txt = server.arg(0);
updateHTML(); updateHTML();
updatePaper(); 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.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.setCursor(20, 40); //Print out instruction on how to connect to Inkplate WiFi and how to open a web page
display.print("Connect to "); display.print("Connect to ");

View File

@ -21,10 +21,11 @@
#include "WiFi.h" //Include library for WiFi #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) 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 *ssid = ""; //Your WiFi SSID
const char* password = ""; //Your WiFi password const char *password = ""; //Your WiFi password
void setup() { void setup()
{
display.begin(); //Init Inkplate library (you should call this function ONLY ONCE) display.begin(); //Init Inkplate library (you should call this function ONLY ONCE)
display.clearDisplay(); //Clear frame buffer of display display.clearDisplay(); //Clear frame buffer of display
display.display(); //Put clear image on display display.display(); //Put clear image on display
@ -35,7 +36,8 @@ void setup() {
//Connect to the WiFi network. //Connect to the WiFi network.
WiFi.mode(WIFI_MODE_STA); WiFi.mode(WIFI_MODE_STA);
WiFi.begin(ssid, password); WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) { while (WiFi.status() != WL_CONNECTED)
{
delay(500); delay(500);
display.print("."); display.print(".");
display.partialUpdate(); display.partialUpdate();
@ -50,7 +52,8 @@ void setup() {
//certain softwares. //certain softwares.
//Forth parameter will dither the image. //Forth parameter will dither the image.
//Photo taken by: Roberto Fernandez //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. //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! //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"); display.println("Image open error");
@ -70,11 +73,14 @@ void setup() {
//Check response code. //Check response code.
int httpCode = http.GET(); int httpCode = http.GET();
if (httpCode == 200) { if (httpCode == 200)
{
//Get the response length and make sure it is not 0. //Get the response length and make sure it is not 0.
int32_t len = http.getSize(); int32_t len = http.getSize();
if (len > 0) { if (len > 0)
if (!display.drawBitmapFromWeb(http.getStreamPtr(), 0, 0, len)) { {
if (!display.drawBitmapFromWeb(http.getStreamPtr(), 0, 0, len))
{
//If is something failed (wrong filename or wrong bitmap format), write error message on the screen. //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! //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"); display.println("Image open error");
@ -82,12 +88,14 @@ void setup() {
} }
display.display(); display.display();
} }
else { else
{
display.println("Invalid response length"); display.println("Invalid response length");
display.display(); display.display();
} }
} }
else { else
{
display.println("HTTP error"); display.println("HTTP error");
display.display(); display.display();
} }
@ -97,6 +105,7 @@ void setup() {
WiFi.mode(WIFI_OFF); WiFi.mode(WIFI_OFF);
} }
void loop() { void loop()
{
//Nothing... //Nothing...
} }

View File

@ -22,8 +22,8 @@
#include "Inkplate.h" //Include Inkplate library to the sketch #include "Inkplate.h" //Include Inkplate library to the sketch
#include "SdFat.h" //Include library for SD card #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 SdFile file; // Create SdFile object used for accessing files on SD card
void setup() void setup()

View File

@ -55,10 +55,9 @@ Inkplate display(INKPLATE_1BIT);
Network network; Network network;
// Contants used for drawing icons // Contants used for drawing icons
char abbrs[32][16] ={ "sn", "sl", "h", "t", "hr", "lr", "s", "hc", "lc", "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 *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 }; 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 abbr1[16];
char abbr2[16]; char abbr2[16];
@ -66,7 +65,7 @@ char abbr3[16];
char abbr4[16]; char abbr4[16];
// Variables for storing temperature // Variables for storing temperature
char temps[8][4] ={ char temps[8][4] = {
"0F", "0F",
"0F", "0F",
"0F", "0F",
@ -74,7 +73,7 @@ char temps[8][4] ={
}; };
// Variables for storing days of the week // Variables for storing days of the week
char days[8][4] ={ char days[8][4] = {
"", "",
"", "",
"", "",
@ -160,8 +159,6 @@ void loop()
else else
display.partialUpdate(); display.partialUpdate();
// Go to sleep before checking again // Go to sleep before checking again
esp_sleep_enable_timer_wakeup(1000L * DELAY_MS); esp_sleep_enable_timer_wakeup(1000L * DELAY_MS);
(void)esp_light_sleep_start(); (void)esp_light_sleep_start();

View File

@ -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) void Shapes::drawThickLine(int x1, int y1, int x2, int y2, int color, float thickness)
{ {
float deg = atan2f((float)(y2 - y1), (float)(x2 - x1)); float deg = atan2f((float)(y2 - y1), (float)(x2 - x1));

View File

@ -3,11 +3,13 @@
#include "../libs/Adafruit-GFX-Library/Adafruit_GFX.h" #include "../libs/Adafruit-GFX-Library/Adafruit_GFX.h"
#include "Arduino.h" #include "Arduino.h"
#include "Triangulate.h"
#define maxVer 100
#define maxHt 600
class Shapes : virtual public Adafruit_GFX class Shapes : virtual public Adafruit_GFX
{ {
public: public:
Shapes(int16_t w, int16_t h) : Adafruit_GFX(w, h){}; Shapes(int16_t w, int16_t h) : Adafruit_GFX(w, h){};
virtual void drawPixel(int16_t x, int16_t y, uint16_t color) = 0; 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 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); void drawGradientLine(int x1, int y1, int x2, int y2, int color1, int color2, float thickness = -1);
private: private:
Triangulate triangulate; 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 startWrite(void) = 0;
virtual void writePixel(int16_t x, int16_t y, uint16_t color) = 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 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 writeLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color) = 0;
virtual void endWrite(void) = 0; virtual void endWrite(void) = 0;
edgeTableTuple *edgeTable, activeEdgeTuple;
}; };
#endif #endif

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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

View File

@ -0,0 +1 @@
#include "Inkplate.h"

View File

@ -0,0 +1 @@
#include "Inkplate.h"

View File

@ -1,6 +1,8 @@
#include "Inkplate.h" #include "Inkplate.h"
#include "SdFat.h" #include "SdFat.h"
const int n = 10;
Inkplate display(INKPLATE_1BIT); Inkplate display(INKPLATE_1BIT);
void setup() void setup()
@ -11,20 +13,42 @@ void setup()
display.joinAP("e-radionica.com", "croduino"); display.joinAP("e-radionica.com", "croduino");
Serial.println(); Serial.println("aaaa");
delay(500); delay(500);
} }
void loop() void loop()
{ {
display.clearDisplay(); 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); delay(5000);
} }