I want to detect if I click inside a diamond. The only thing I have are the coordinates of the click (x,y), the center of the diamond (x,y) and the width/height of the diamond.
I found this, but the problem is different. pixel coordinates on diamond
The answer that you linked actually contains everything you need: You can do the "Direct point position check" to detect whether a point is inside the diamond.
I assume that the diamonds can not be rotated or so, otherwise, the question would have been horribly imprecise.
Here is an MCVE, implemented in Java/Swing as an example:
The relevant part is actually the Diamond#contains
method at the bottom, which consists of the 4 lines of code taken from the other answer....
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.geom.Path2D;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class DiamondClickTest
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
createAndShowGUI();
}
});
}
private static void createAndShowGUI()
{
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
List<Diamond> diamonds = new ArrayList<Diamond>();
diamonds.add(new Diamond("A", new Point(100,100), 180, 140));
diamonds.add(new Diamond("B", new Point(300,100), 110, 160));
diamonds.add(new Diamond("C", new Point(100,300), 110, 180));
diamonds.add(new Diamond("D", new Point(300,300), 130, 150));
DiamondClickTestPanel p = new DiamondClickTestPanel(diamonds);
f.getContentPane().add(p);
f.setSize(400,430);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
class DiamondClickTestPanel extends JPanel implements MouseMotionListener
{
private List<Diamond> diamonds;
private Diamond highlighedDiamond = null;
DiamondClickTestPanel(List<Diamond> diamonds)
{
this.diamonds = diamonds;
addMouseMotionListener(this);
}
@Override
protected void paintComponent(Graphics gr)
{
super.paintComponent(gr);
Graphics2D g = (Graphics2D)gr;
g.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
for (Diamond diamond : diamonds)
{
draw(g, diamond);
}
}
private void draw(Graphics2D g, Diamond diamond)
{
Point2D c = diamond.getCenter();
double x0 = c.getX() + diamond.getWidth() * 0.5;
double y0 = c.getY();
double x1 = c.getX();
double y1 = c.getY() - diamond.getHeight() * 0.5;
double x2 = c.getX() - diamond.getWidth() * 0.5;
double y2 = c.getY();
double x3 = c.getX();
double y3 = c.getY() + diamond.getHeight() * 0.5;
Path2D p = new Path2D.Double();
p.moveTo(x0, y0);
p.lineTo(x1, y1);
p.lineTo(x2, y2);
p.lineTo(x3, y3);
p.closePath();
if (diamond == highlighedDiamond)
{
g.setColor(Color.RED);
g.fill(p);
}
g.setColor(Color.BLACK);
g.draw(p);
g.drawString(diamond.getName(), (int)c.getX()-4, (int)c.getY()+8);
}
@Override
public void mouseDragged(MouseEvent e)
{
}
@Override
public void mouseMoved(MouseEvent e)
{
double x = e.getX();
double y = e.getY();
highlighedDiamond = null;
for (Diamond diamond : diamonds)
{
if (diamond.contains(x, y))
{
highlighedDiamond = diamond;
}
}
repaint();
}
}
class Diamond
{
private String name;
private Point2D center;
private double width;
private double height;
Diamond(String name, Point2D center, double width, double height)
{
this.name = name;
this.center = center;
this.width = width;
this.height = height;
}
String getName()
{
return name;
}
Point2D getCenter()
{
return center;
}
double getWidth()
{
return width;
}
double getHeight()
{
return height;
}
boolean contains(double x, double y)
{
double dx = Math.abs(x - center.getX());
double dy = Math.abs(y - center.getY());
double d = dx / width + dy / height;
return d <= 0.5;
}
}