]> git.basschouten.com Git - openhab-addons.git/blob
3cabae992e80e6bea6a7ebb844b212eb4d7cca1f
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2023 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
7  * This program and the accompanying materials are made available under the
8  * terms of the Eclipse Public License 2.0 which is available at
9  * http://www.eclipse.org/legal/epl-2.0
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.nanoleaf.internal.layout.shape;
14
15 import java.awt.Color;
16 import java.awt.Graphics2D;
17 import java.awt.Polygon;
18 import java.util.ArrayList;
19 import java.util.Collections;
20 import java.util.List;
21
22 import org.eclipse.jdt.annotation.NonNullByDefault;
23 import org.openhab.binding.nanoleaf.internal.layout.DrawingSettings;
24 import org.openhab.binding.nanoleaf.internal.layout.ImagePoint2D;
25 import org.openhab.binding.nanoleaf.internal.layout.PanelState;
26 import org.openhab.binding.nanoleaf.internal.layout.Point2D;
27 import org.openhab.binding.nanoleaf.internal.layout.ShapeType;
28 import org.openhab.binding.nanoleaf.internal.model.PositionDatum;
29 import org.openhab.core.library.types.HSBType;
30
31 /**
32  * A hexagon shape.
33  *
34  * @author Jørgen Austvik - Initial contribution
35  */
36 @NonNullByDefault
37 public class HexagonCorners extends Panel {
38
39     private static final int CORNER_DIAMETER = 4;
40
41     private final List<PositionDatum> corners;
42
43     public HexagonCorners(ShapeType shapeType, List<PositionDatum> corners) {
44         super(shapeType);
45
46         this.corners = Collections.unmodifiableList(new ArrayList<>(corners));
47     }
48
49     @Override
50     public List<Point2D> generateOutline() {
51         List<Point2D> result = new ArrayList<>(corners.size());
52         for (PositionDatum corner : corners) {
53             result.add(new Point2D(corner.getPosX(), corner.getPosY()));
54         }
55
56         return result;
57     }
58
59     @Override
60     public void draw(Graphics2D graphics, DrawingSettings settings, PanelState state) {
61         List<ImagePoint2D> outline = settings.generateImagePoints(generateOutline());
62         Polygon p = new Polygon();
63         for (int i = 0; i < outline.size(); i++) {
64             ImagePoint2D pos = outline.get(i);
65             p.addPoint(pos.getX(), pos.getY());
66         }
67
68         if (settings.shouldFillWithColor()) {
69             Color averageColor = getAverageColor(state);
70             graphics.setColor(averageColor);
71             graphics.fillPolygon(p);
72
73             // Draw color cradient
74             ImagePoint2D center = findCenter(outline);
75             for (int i = 0; i < outline.size(); i++) {
76                 ImagePoint2D corner1Pos = outline.get(i);
77                 ImagePoint2D corner2Pos = outline.get((i + 1) % outline.size());
78
79                 PositionDatum corner1 = corners.get(i);
80                 PositionDatum corner2 = corners.get((i + 1) % outline.size());
81
82                 Color corner1Color = getColor(corner1.getPanelId(), state);
83                 Color corner2Color = getColor(corner2.getPanelId(), state);
84                 graphics.setPaint(new BarycentricTriangleGradient(
85                         new ImagePoint2D(corner1Pos.getX(), corner1Pos.getY()), corner1Color,
86                         new ImagePoint2D(corner2Pos.getX(), corner2Pos.getY()), corner2Color, center, averageColor));
87
88                 Polygon wedge = new Polygon();
89                 wedge.addPoint(corner1Pos.getX(), corner1Pos.getY());
90                 wedge.addPoint(corner2Pos.getX(), corner2Pos.getY());
91                 wedge.addPoint(center.getX(), center.getY());
92                 graphics.fillPolygon(p);
93             }
94         }
95
96         if (settings.shouldDrawOutline()) {
97             graphics.setColor(settings.getOutlineColor());
98             graphics.drawPolygon(p);
99         }
100
101         if (settings.shouldDrawCorners()) {
102             for (PositionDatum corner : corners) {
103                 ImagePoint2D position = settings.generateImagePoint(new Point2D(corner.getPosX(), corner.getPosY()));
104                 graphics.setColor(getColor(corner.getPanelId(), state));
105                 graphics.fillOval(position.getX() - CORNER_DIAMETER / 2, position.getY() - CORNER_DIAMETER / 2,
106                         CORNER_DIAMETER, CORNER_DIAMETER);
107
108                 if (settings.shouldDrawOutline()) {
109                     graphics.setColor(settings.getOutlineColor());
110                     graphics.drawOval(position.getX() - CORNER_DIAMETER / 2, position.getY() - CORNER_DIAMETER / 2,
111                             CORNER_DIAMETER, CORNER_DIAMETER);
112                 }
113             }
114         }
115
116         if (settings.shouldDrawLabels()) {
117             graphics.setColor(settings.getLabelColor());
118
119             for (PositionDatum corner : corners) {
120                 ImagePoint2D position = settings.generateImagePoint(new Point2D(corner.getPosX(), corner.getPosY()));
121                 graphics.drawString(Integer.toString(corner.getPanelId()), position.getX(), position.getY());
122             }
123         }
124     }
125
126     private ImagePoint2D findCenter(List<ImagePoint2D> outline) {
127         Point2D[] bounds = findBounds(outline);
128         int midX = bounds[0].getX() + (bounds[1].getX() - bounds[0].getX()) / 2;
129         int midY = bounds[0].getY() + (bounds[1].getY() - bounds[0].getY()) / 2;
130         return new ImagePoint2D(midX, midY);
131     }
132
133     private static Color getColor(int panelId, PanelState state) {
134         HSBType color = state.getHSBForPanel(panelId);
135         return new Color(color.getRGB());
136     }
137
138     private Color getAverageColor(PanelState state) {
139         float r = 0;
140         float g = 0;
141         float b = 0;
142         for (PositionDatum corner : corners) {
143             Color c = getColor(corner.getPanelId(), state);
144             r += c.getRed() * c.getRed();
145             g += c.getGreen() * c.getGreen();
146             b += c.getBlue() * c.getBlue();
147         }
148
149         return new Color((int) Math.sqrt((double) r / corners.size()), (int) Math.sqrt((double) g / corners.size()),
150                 (int) Math.sqrt((double) b / corners.size()));
151     }
152 }