簡體   English   中英

計算圓上的點[Java /處理]

[英]Calculating Points on a Circle [Java / Processing]

我需要計算紅線(在下圖上)與圓的圓周相交的位置。 問題是我不知道它們將以什么角度(從中心)越過圓周。

我唯一知道的是圓的半徑(由藍線表示)和紅線的x位置(每條線以radius / 4偏移,由綠線表示)。

任何形式的數學解決方案將不勝感激,但是對於Java / Processing來說 ,這是加分點。

圈子和東西

您知道水平值,即從紅線到中心的距離。 我們稱呼它為“ horz

您已經知道半徑,因此可以將角度設為

Math.acos(horz / radius)

(已解決,未經測試)

對於歸一化的坐標,y坐標的計算為

private static double computeY(double x)
{
    return Math.sin(Math.acos(x));
}

“規范化”是指

  • 參數x是一個介於0.0和1.0之間的值,該值是根據絕對坐標除以半徑得出的
  • 結果y是0.0到1.0之間的值,可以通過乘以半徑將其轉換為絕對坐標

如果只需要角度,則可以簡單地計算為Math.acos(x)

結果看起來像這樣:

在此處輸入圖片說明

編碼:

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.io.IOException;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;


public class CircleIntersectionTest
{
    public static void main(String[] args) throws IOException
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {
                createAndShowGUI();
            }
        });
    }

    private static void createAndShowGUI()
    {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.getContentPane().add(new CircleIntersectionPanel());
        f.setSize(500,500);
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }
}

class CircleIntersectionPanel extends JPanel
    implements MouseMotionListener
{
    private Point mousePosition = null;

    CircleIntersectionPanel()
    {
        addMouseMotionListener(this);
    }

    @Override
    protected void paintComponent(Graphics gr)
    {
        super.paintComponent(gr);
        Graphics2D g = (Graphics2D)gr;

        double centerX = getWidth() / 2;
        double centerY = getHeight() / 2;
        double radius = 200;

        g.setStroke(new BasicStroke(2));
        g.setColor(Color.BLACK);;
        g.draw(new Ellipse2D.Double(
            centerX-radius, centerY-radius, 
            radius+radius, radius+radius));
        if (mousePosition == null)
        {
            return;
        }

        g.setColor(Color.RED);
        g.draw(new Line2D.Double(
            mousePosition.x, centerY, mousePosition.x, 0));

        g.setColor(Color.BLUE);

        double x = (mousePosition.x - centerX) / radius;
        double y = computeY(x);

        double cx = centerX + radius * x;
        double cy = centerY - radius * y;
        g.fill(new Ellipse2D.Double(cx-8, cy-8, 16, 16));

        g.setColor(Color.BLACK);
        g.drawString("x = "+x, 10, 30);
        g.drawString("y = "+y, 10, 46);
        g.drawString("angle: "+Math.toDegrees(Math.acos(x)), 10, 62);

    }

    private static double computeY(double x)
    {
        return Math.sin(Math.acos(x));
    }


    @Override
    public void mouseMoved(MouseEvent e)
    {
        mousePosition = e.getPoint();
        repaint();
    }

    @Override
    public void mouseDragged(MouseEvent e)
    {
    }

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM