2010-12-10 4 views
2

Есть ли способ проверить, находится ли данная точка на кривой? Я имею в виду ход кривой, а не границы.Мышь над кривой

Вот простой тест программы, которые вы можете запустить:

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(); 
    } 

} 

Я хочу mouseMoved печать «истина» только тогда, когда мышь находится над инсультом (красная линия) и ложь в противном случае.

Это похоже на тривиальную вещь, но я не могу понять, как я могу заставить ее работать.

Пожалуйста, помогите.

ответ

3

Graphics Gems (by Andrew Glassner) имеет решение проблемы с ближайшей точкой на кривой. Вы можете скачать source code для книги и посмотреть на NearestPoint.c. Я также нашел java translation кода c, но не могу гарантировать, что он работает. Этот код поможет вам найти ближайшую точку на кривой из точки курсора.

Как только у вас есть ближайшая точка на кривой, вы можете найти расстояние между двумя точками, используя Point2D#distance, и если расстояние ничтожно, точка курсора находится на кривой.

+0

Спасибо, миллион! Оно работает! Хотя мне пришлось исправить NullPointerException, так как в коде кто-то пытается установитьLocation неинициализированных точек ... Я дам разработчикам знать об этой проблеме. – Artur 2010-12-10 17:12:35

0

Я попытался бы вычислить (кратчайшее) расстояние между курсором мыши и кривой вручную - хотя нетривиальный расчет.

3

Существует два разумных способа сделать это. Один из них - математически определить расстояние от точки мыши до кривой. Это не тривиальная операция и предполагает точное знание математического определения кривой, определенной CubiCurve2D, но учитывая, что вы должны это сделать.

Второй заключается в том, чтобы использовать тот же подход, что и OpenGl, и использовать кривую (возможно, для растрового изображения вне экрана), установить все рисованные пиксели, а затем выяснить, включен ли пиксель мыши на этих пикселях. Который вы выбираете, вероятно, является компромиссом в использовании ресурсов и сложности разработчика.

0

Вы можете разделить свою кривую на несколько коротких линий (используя определение Безье, вы можете сделать это тривиально), а затем вычислить расстояние от указателя мыши до каждой из этих строк, используя метод «дистанция» Line2D. И когда вы узнаете минимум этих расстояний, вы сможете сказать, что это указатель мыши над ним или нет.

0

Ну, вы могли бы просто проверить, красный ли пиксель в координатах (или около) мыши? Наверное, не то, что вы ищете, если дело усложняется.

Смежные вопросы