]> git.basschouten.com Git - openhab-addons.git/blob
ecc3b5d90d83f3e609bbebf5468d374d83f39d42
[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 import org.openhab.core.util.ColorUtil;
31
32 /**
33  * A hexagon shape.
34  *
35  * @author Jørgen Austvik - Initial contribution
36  */
37 @NonNullByDefault
38 public class HexagonCorners extends Panel {
39
40     private static final int CORNER_DIAMETER = 4;
41
42     private final List<PositionDatum> corners;
43
44     public HexagonCorners(ShapeType shapeType, List<PositionDatum> corners) {
45         super(shapeType);
46
47         this.corners = Collections.unmodifiableList(new ArrayList<>(corners));
48     }
49
50     @Override
51     public List<Point2D> generateOutline() {
52         List<Point2D> result = new ArrayList<>(corners.size());
53         for (PositionDatum corner : corners) {
54             result.add(new Point2D(corner.getPosX(), corner.getPosY()));
55         }
56
57         return result;
58     }
59
60     @Override
61     public void draw(Graphics2D graphics, DrawingSettings settings, PanelState state) {
62         List<ImagePoint2D> outline = settings.generateImagePoints(generateOutline());
63         Polygon p = new Polygon();
64         for (int i = 0; i < outline.size(); i++) {
65             ImagePoint2D pos = outline.get(i);
66             p.addPoint(pos.getX(), pos.getY());
67         }
68
69         if (settings.shouldFillWithColor()) {
70             Color averageColor = getAverageColor(state);
71             graphics.setColor(averageColor);
72             graphics.fillPolygon(p);
73
74             // Draw color cradient
75             ImagePoint2D center = findCenter(outline);
76             for (int i = 0; i < outline.size(); i++) {
77                 ImagePoint2D corner1Pos = outline.get(i);
78                 ImagePoint2D corner2Pos = outline.get((i + 1) % outline.size());
79
80                 PositionDatum corner1 = corners.get(i);
81                 PositionDatum corner2 = corners.get((i + 1) % outline.size());
82
83                 Color corner1Color = getColor(corner1.getPanelId(), state);
84                 Color corner2Color = getColor(corner2.getPanelId(), state);
85                 graphics.setPaint(new BarycentricTriangleGradient(
86                         new ImagePoint2D(corner1Pos.getX(), corner1Pos.getY()), corner1Color,
87                         new ImagePoint2D(corner2Pos.getX(), corner2Pos.getY()), corner2Color, center, averageColor));
88
89                 Polygon wedge = new Polygon();
90                 wedge.addPoint(corner1Pos.getX(), corner1Pos.getY());
91                 wedge.addPoint(corner2Pos.getX(), corner2Pos.getY());
92                 wedge.addPoint(center.getX(), center.getY());
93                 graphics.fillPolygon(p);
94             }
95         }
96
97         if (settings.shouldDrawOutline()) {
98             graphics.setColor(settings.getOutlineColor());
99             graphics.drawPolygon(p);
100         }
101
102         if (settings.shouldDrawCorners()) {
103             for (PositionDatum corner : corners) {
104                 ImagePoint2D position = settings.generateImagePoint(new Point2D(corner.getPosX(), corner.getPosY()));
105                 graphics.setColor(getColor(corner.getPanelId(), state));
106                 graphics.fillOval(position.getX() - CORNER_DIAMETER / 2, position.getY() - CORNER_DIAMETER / 2,
107                         CORNER_DIAMETER, CORNER_DIAMETER);
108
109                 if (settings.shouldDrawOutline()) {
110                     graphics.setColor(settings.getOutlineColor());
111                     graphics.drawOval(position.getX() - CORNER_DIAMETER / 2, position.getY() - CORNER_DIAMETER / 2,
112                             CORNER_DIAMETER, CORNER_DIAMETER);
113                 }
114             }
115         }
116
117         if (settings.shouldDrawLabels()) {
118             graphics.setColor(settings.getLabelColor());
119
120             for (PositionDatum corner : corners) {
121                 ImagePoint2D position = settings.generateImagePoint(new Point2D(corner.getPosX(), corner.getPosY()));
122                 graphics.drawString(Integer.toString(corner.getPanelId()), position.getX(), position.getY());
123             }
124         }
125     }
126
127     private ImagePoint2D findCenter(List<ImagePoint2D> outline) {
128         Point2D[] bounds = findBounds(outline);
129         int midX = bounds[0].getX() + (bounds[1].getX() - bounds[0].getX()) / 2;
130         int midY = bounds[0].getY() + (bounds[1].getY() - bounds[0].getY()) / 2;
131         return new ImagePoint2D(midX, midY);
132     }
133
134     private static Color getColor(int panelId, PanelState state) {
135         HSBType color = state.getHSBForPanel(panelId);
136         return new Color(ColorUtil.hsbTosRgb(color));
137     }
138
139     private Color getAverageColor(PanelState state) {
140         float r = 0;
141         float g = 0;
142         float b = 0;
143         for (PositionDatum corner : corners) {
144             Color c = getColor(corner.getPanelId(), state);
145             r += c.getRed() * c.getRed();
146             g += c.getGreen() * c.getGreen();
147             b += c.getBlue() * c.getBlue();
148         }
149
150         return new Color((int) Math.sqrt((double) r / corners.size()), (int) Math.sqrt((double) g / corners.size()),
151                 (int) Math.sqrt((double) b / corners.size()));
152     }
153 }