开发者

Mouse over curve

开发者 https://www.devze.com 2023-01-29 17:10 出处:网络
Is there a way of checking if a given point lies on a curve? I mean the stroke of a curve not it\'s boundaries.

Is there a way of checking if a given point lies on a curve? I mean the stroke of a curve not it's boundaries.

Here is a simple test program that you can run:

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;

import javax.swing.JFrame;


public class Test extends Canvas implements MouseMotionListener {

    private JFrame frame;
    private CubicCurve2D curve;
    private static final int OFFSET = 1000;

    public Test() {
        frame = new JFrame();

        addMouseMotionListener(this);
        setPreferredSize(new Dimension(800, 600));
        setBackground(Color.WHITE);

        frame.add(this);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);

        Graphics2D g2 = (Graphics2D) g;

        curve = new CubicCurve2D.Double(10, 100, 700, -500
                + Math.random() * OFFSET, -500 + Math.random() * OFFSET, 700,
                590, 500);

        g2.setPaint(Color.RED);
        g2.setStroke(new BasicStroke(2));
        g2.draw(curve);

        g2.setPaint(Color.lightGray);
        g2.fill(curve);
    }

  开发者_如何转开发  @Override
    public void mouseMoved(MouseEvent e) {
        System.out.println(curve.contains(e.getX(), e.getY()));
    }

    @Override
    public void mouseDragged(MouseEvent e) {}

    public static void main(String[] args) {
        new Test();
    }

}

I want mouseMoved print "true" only when mouse is over the stroke (red line) and false otherwise.

It feels like a trivial thing to do, but I cannot figure out how can I get it to work.

Please help.


Graphics Gems (by Andrew Glassner) has a solution for the nearest-point-on-curve problem. You can download the source code for the book and take a look at NearestPoint.c. I also found a java translation of the c code, but can't guarantee that it works. This code will help you find the nearest point on the curve from the cursor point.

Once you have the nearest point on the curve, you can then find the distance between the two points using Point2D#distance and if the distance is negligible, the cursor point is on the curve.


There are two reasonable ways to do this. One is to mathematically work out the distance from the mouse point to the curve. This isn't a trivial operation, and involves knowing exactly the mathematical definition of the curve defined by CubiCurve2D, but given that you should be able to do it.

The second is to take the same approach OpenGl does and to darw the curve (possibly to an offscreen bitmap), setting all the drawn pixels, and then find out if the pixel the mouse is on is on eof those pixels. Which you choose is probably a tradeoff in resources used versus developer complexity.


I'd try to calculate the (shortest) distance between the mouse cursor and your curve manually - though a non-trivial calculation.


You can split your curve into many short lines (using Bezier definition, you can do that trivially), and then calculate distance from mouse pointer to each of this lines using Line2D's method "distance". And when you'll know the minimum of that distances, you'll be able to say, is your mouse pointer over it, or not.


Well, you could simply check, whether the pixel at (or near the) mouse coordinates is red? Probably not what you are lookin for, if the case gets more complex.

0

精彩评论

暂无评论...
验证码 换一张
取 消