Sindbad~EG File Manager
/**
* This class represents a Ray displayed by Diagrammer.
* File: Ray.java
*
* This code is in the public domain.
*
* @author Brian Chan
*/
// 12.24.06 Beeson changed color to GREEN
package org.dynamicgeometry.diagrammer;
import java.awt.*;
import java.awt.font.FontRenderContext;
import java.awt.font.TextLayout;
import java.awt.geom.Point2D;
public class Ray extends Line {
/**
* A constructor for Ray
*
*/
public Ray()
{
// calls a constructor of Line
super();
}
/**
* A constructor for Ray
*
* @param A the end Point of the Ray
* @param B a point that lies on the Ray
*/
public Ray(Point A, Point B)
{
super(A,B);
}
/**
* Draws a Ray using the Graphics2D parameter.
*
* @param g the Object used to draw an Arc
*/
public void draw(Graphics2D g)
{
Point a,
b;
// Checks if Arguments contains the proper values to draw a Line
// draw if visible
if(this.visible &&
this.Arguments.size() == 2 &&
(a = (Point)Arguments.get(0)) instanceof Point &&
(b = (Point)Arguments.get(1)) instanceof Point)
{
Rectangle rect = g.getClipBounds();
// if this Object is input
if(this.isInput != 0)
{
// if this Object is selected and is input
if(this.selected)
g.setColor(Color.GREEN);
// if this Object is not selected but is input
else
g.setColor(Color.BLUE);
}
// if this Object is not input
else
{
// if this Object is selected and is input
if(this.selected)
g.setColor(Color.RED);
// if this Object is not selected but is input
else
g.setColor(Color.GRAY);
}
// if the Ray is horizontal
if(b.y == a.y)
{
g.drawLine((int)a.x,
(int)b.y,
(int)((a.x > b.x)?0:rect.width),
(int)b.y);
}
// if the Ray is vertical
else if(b.x == a.x)
{
g.drawLine((int)a.x,
(int)a.y,
(int)b.x,
(int)((a.y > b.y)?0:rect.height));
}
else
{
double slope = (0.0 + b.y - a.y) / (0.0 + b.x - a.x);
double base = (a.x < b.x)?a.y:b.y;
double y = slope * (rect.width - Math.min(a.x, b.x)) + base;
Point p1 = new Point();
// calculates the Point p1 where the Ray intersects the bounding box
if(b.x > a.x)
{
if(y < 0)
{
p1.x = Math.min(a.x, b.x) + (int)((-1 * base)/slope);
p1.y = 0;
}
else if(y > rect.height)
{
p1.x = Math.max(a.x, b.x) + (int)((rect.height - Math.max(a.y, b.y))/slope);
p1.y = rect.height;
}
else
{
p1.x = rect.width;
p1.y = (int)y;
}
}
else
{
y = slope * -1 * Math.min(a.x, b.x) + base;
if(y < 0)
{
p1.x = Math.min(a.x, b.x) + (int)((-1 * base)/slope);
p1.y = 0;
}
else if(y > rect.height)
{
p1.x = Math.min(a.x, b.x) +
(int)( (rect.height - Math.max(a.y, b.y) ) / slope);
p1.y = rect.height;
}
else
{
p1.x = 0;
p1.y = (int)y;
}
}
g.drawLine((int)a.x, (int)a.y, (int)p1.x, (int)p1.y);
}
// Draws the Label for this Ray if it is initilized and visible
if(this.label != null && this.label.getVisible())
{
FontRenderContext frc = g.getFontRenderContext();
TextLayout layout = new TextLayout(this.label.toString(),
this.label.getFont(),
frc);
this.label.setLocation(
new Point2D.Double(
(a.x + b.x) / 2 + EPSILON,
(a.y + b.y) / 2 + EPSILON));
layout.draw(g,
(float)this.label.getLocation().getX(),
(float)this.label.getLocation().getY() );
}
}
}
/**
* Determines if a mouse click is "close" enough to constitute a mouse
* click for this Object.
*
* Code used from:
* http://local.wasp.uwa.edu.au/~pbourke/geometry/sphereline/raysphere.c
*
* @param x the x coordinate of the mouse click
* @param y the y coordinate of this mouse click
* @return true if this Object was clicked, false if this Object was not clicked
*/
public boolean clickedOn(double x, double y)
{
Point p1,
p2,
sc,
dp;
// checks if there are valid Arguments for this Line and is visible
if(this.visible &&
this.Arguments.size() == 2 &&
(p1 = (Point)Arguments.get(0)) instanceof Point &&
(p2 = (Point)Arguments.get(1)) instanceof Point)
{
sc = new Point(x, y);
dp = new Point();
double r = EPSILON,
a,
b,
c,
mu1,
mu2,
bb4ac;
dp.x = p2.x - p1.x;
dp.y = p2.y - p1.y;
a = dp.x * dp.x + dp.y * dp.y;
b = 2 * (dp.x * (p1.x - sc.x) + dp.y * (p1.y - sc.y));
c = sc.x * sc.x + sc.y * sc.y;
c += p1.x * p1.x + p1.y * p1.y;
c -= 2 * (sc.x * p1.x + sc.y * p1.y);
c -= r * r;
bb4ac = b * b - 4 * a * c;
if (bb4ac < 0)
return(false);
mu1 = (-b + Math.sqrt(bb4ac)) / (2 * a);
mu2 = (-b - Math.sqrt(bb4ac)) / (2 * a);
return (mu1 > 0 || mu2 > 0);
}
// otherwise, return false
else return false;
}
}
Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists