2 * Copyright (c) 2010-2023 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
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
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.nanoleaf.internal.layout.shape;
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;
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;
35 * @author Jørgen Austvik - Initial contribution
38 public class HexagonCorners extends Panel {
40 private static final int CORNER_DIAMETER = 4;
42 private final List<PositionDatum> corners;
44 public HexagonCorners(ShapeType shapeType, List<PositionDatum> corners) {
47 this.corners = Collections.unmodifiableList(new ArrayList<>(corners));
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()));
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());
69 if (settings.shouldFillWithColor()) {
70 Color averageColor = getAverageColor(state);
71 graphics.setColor(averageColor);
72 graphics.fillPolygon(p);
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());
80 PositionDatum corner1 = corners.get(i);
81 PositionDatum corner2 = corners.get((i + 1) % outline.size());
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));
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);
97 if (settings.shouldDrawOutline()) {
98 graphics.setColor(settings.getOutlineColor());
99 graphics.drawPolygon(p);
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);
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);
117 if (settings.shouldDrawLabels()) {
118 graphics.setColor(settings.getLabelColor());
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());
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);
134 private static Color getColor(int panelId, PanelState state) {
135 HSBType color = state.getHSBForPanel(panelId);
136 return new Color(ColorUtil.hsbTosRgb(color));
139 private Color getAverageColor(PanelState state) {
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();
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()));