JakeSidSmith
JakeSidSmith

Reputation: 933

Calculating Points on a Circle

I need to calculate where the red lines (on the image below) cross the circumference of the circle. The problem is I don't know at what angle (from the center) they will cross the circumference.

The only things I know are the radius of the circle (represented by the blue line) and the x positions of the red lines (each offset by radius/4, represented by the green line).

A mathematical solution of any kind would be appreciated, but bonus points for Java / Processing.

Circles and stuff

Upvotes: 0

Views: 2282

Answers (2)

Marco13
Marco13

Reputation: 54611

For normalized coordinates, the computation for the y-coordinate is

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

"Normalized" means that

  • The parameter x is a value between 0.0 and 1.0 which be computed from the absolute coordinates by dividing by the radius
  • the result, y, is a value between 0.0 and 1.0, that can be converted to an absolute coordinates by multiplying with the radius

If you only need the angle, this can simply be computed as Math.acos(x)

The result looks like this:

enter image description here

The code:

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)
    {
    }

}

Upvotes: 2

Evan Knowles
Evan Knowles

Reputation: 7501

You know the horizontal value, being the distance from the red line to the center. Let's call that horz.

You know the radius already, so you can get the angle as

Math.acos(horz / radius)

(worked out, not tested)

Upvotes: 2

Related Questions