Reputation: 933
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.
Upvotes: 0
Views: 2282
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
x
is a value between 0.0 and 1.0 which be computed from the absolute coordinates by dividing by the radiusy
, 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:
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
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