lineseg.java
来自「用Java开发的、实现类似Visio功能的应用程序源码」· Java 代码 · 共 1,182 行 · 第 1/3 页
JAVA
1,182 行
/**
* Tests if the specified line segment intersects the this
* <code>LineSeg</code>.
* @param l the specified {@link LineSeg} to test for intersection
* with this <code>LineSeg</code>
* @return <code>true</code> if the specified <code>LineSeg</code>
* intersects this <code>LineSeg</code>;
* <code>false</code> otherwise.
* @since 1.2
*/
public boolean intersects(LineSeg l) {
if (l==null)
return false;
else
return intersects(l.getX1(), l.getY1(), l.getX2(), l.getY2());
}
/**
* Tests if the specified line segment intersects this
* <code>LineSeg</code>.
*
* @param startPoint the first endpoint of the specified
* line segment
* @param endPoint the second endpoint of the specified
* line segment
* @return <code>true</code> if the specified line segment intersects
* the this <code>LineSeg</code>; <code>false</code>
* otherwise.
*/
public boolean intersects(JFPoint startPoint, JFPoint endPoint) {
return intersects(startPoint.getX(),startPoint.getY(),endPoint.getX(),endPoint.getY());
}
/**
* Tests if the specified line segment intersects this
* <code>LineSeg</code>.
*
* @param x1, y1 the first endpoint of the specified
* line segment
* @param x2, y2 the second endpoint of the specified
* line segment
* @return <code>true</code> if the specified line segment intersects
* the this <code>LineSeg</code>; <code>false</code>
* otherwise.
*/
public boolean intersects(double x1, double y1, double x2, double y2) {
JFPoint pnt =intersectsAt(x1,y1,x2,y2);
return (pnt!=null);
}
/**
* Tests if the specified rectangle intersects the interior of this
* <code>LineSeg</code>.
* @param rect the specified {@link Rect} to test for intersection
* with the interior of this <code>LineSeg</code>
* @return <code>true</code> if the specified <code>Rect</code>
* intersects the interior of this <code>LineSeg</code>;
* <code>false</code> otherwise.
*/
public boolean intersects(Rect rect) {
LineSeg side =null;
//test if each side of rectangle intersects.
for (int i = Rect.SIDETYPE_LEFT; i<=Rect.SIDETYPE_BOTTOM; i++){
side =rect.getSide(i);
if (intersects(side))
return true;
}
//test if current rectangle is inside the target rectangle.
return rect.contains(getPoint1()) ||
rect.contains(getPoint2());
}
/**
* Get the slope of this line.
* return 0 if horizontal line, return GeomConst.LARGE_VALUE if vertical line,
* return any double value if otherwise.
*
* @return the slope of this line.
*/
public double getSlope(){
return getSlope(this);
}
/**
* Get the slope of a specified line.
* return 0 if horizontal line, return GeomConst.LARGE_VALUE if vertical line,
* return any double value if otherwise.
*
* @param line A line for test slope.
* @return the slope of this line.
*/
public static double getSlope(LineSeg line){
return getSlope(line.getPoint1(),line.getPoint2());
}
/**
* Get the slope of a specified line.
* return 0 if horizontal line, return GeomConst.LARGE_VALUE if vertical line,
* return any double value if otherwise.
*
* @param startPoint one end point of the line.
*
* @param endPoint the other end point of the line.
*
* @return the slope of this line.
*/
public static double getSlope(JFPoint startPoint, JFPoint endPoint){
return getSlope(startPoint.getX(),startPoint.getY(),endPoint.getX(),endPoint.getY());
}
/**
* Get the slope of a specified line.
* return 0 if horizontal line, return GeomConst.LARGE_VALUE if vertical line,
* return any double value if otherwise.
*
* @param x1, y1 the first specified coordinates
*
* @param x2, y2 the second specified coordinates
*
* @return the slope of this line.
*/
public static double getSlope(double x1, double y1, double x2, double y2){
//general slope of the line: b=(y1-y1)/(x2-x1)
if ((float)x1!=(float)x2){
if ((float)y1==(float)y2)
return 0;
else
return (y2-y1)/(x2-x1);
}else{
//line is vertical, just give it a large slope:
return GeomConst.LARGE_VALUE;
}
}
/**
* Get an intersected point both on this line and a new line.
*
* @param startPoint the first endpoint of the specified
* line segment
* @param endPoint the second endpoint of the specified
* line segment
* @return a intersected point, null if no interception.
*/
public JFPoint intersectsAt(JFPoint startPoint, JFPoint endPoint) {
return intersectsAt(startPoint.getX(),startPoint.getY(),endPoint.getX(),endPoint.getY());
}
/**
* Get an intersected point both on this line and a new line.
*
* The general equation of a line is usually written as y=mx + b where
* m is the slope of the line and b is the intercept.
* Slope is how much the vertical (y) coordinate changes for each unit of
* change in the horizontal direction (x).
* Intercept is where the line crosses the y-axis, i.e. the value of y when x=0.
* <p>
* If we know two points on a line (x1,y1) and (x2,y2), we can determine m and b as follows.
* From its definition, m = change in y divided by change in x = (y2-y1)/(x2-x1).
* And since b=y-mx for any point on the line, we can compute b1=y1-mx1.
* <p>
* With two line segments, we can derive an equation for each, say y=m1x+b1 and y=m2x+b2.
* The x and y values at the intersection point must satisfy both, so y = m1x+b1=m2x+b2.
* If we take the last half of this and solve for x, we get m1x+b1=m2x+b2, or (m1-m2)x=b2-b1
* or x=(b2-b1)/(m1-m2). Notice that when m1 equals m2, the lines are parallel and they
* will never intersect.
*
* The final test is to see if the intersection point is between the endpoints of
* each line segment. This just involves making sure that our x is greater
* than (or equal to) the smallest x endpoint value and smaller than (or equal to)
* the largest endpoint x value for each line.
*
* @param x1, y1 the first endpoint of the specified
* line segment
* @param x2, y2 the second endpoint of the specified
* line segment
* @return a intersected point, null if no interception.
*/
public JFPoint intersectsAt(double x1, double y1, double x2, double y2) {
/*
* We assume the line1 and line2 here.
* line1 = x1,y1 to x2,y2
* line2 = x3,y3 to x4,y4
*/
double x3 =m_point1.getX();
double y3 =m_point1.getY();
double x4 =m_point2.getX();
double y4 =m_point2.getY();
double slope1,slope2 =0;
double intercept1,intercept2 =0;
double x,y =0;
/*
Method -
a. find the equations of the lines,
b. find where they intersect
c. if the point is between the line segment end points for both lines,
then they do intersect, otherwise not.
*/
//general equation of the new line: y=mx+b
slope1 =getSlope(x1,y1,x2,y2);
intercept1 =y1-slope1*x1;
//general equation of this line: y=mx+b
slope2 =getSlope(x3,y3,x4,y4);
intercept2 =y3-slope2*x3;
/*
intersection condition
any point (x,y) on line1 satisfies y=m1*x+b1, the intersection
point also satisfies the line2 equation y=m2*x+b2,
so y=m1*x+b1=m2*x+b2
*/
/*
solve for X -
m1*x+b1=m2*x+b2
x=(b2-b1)/(m1-m2)
*/
if (slope1==slope2){
//the two lines are parallel
if (intercept1!=intercept2){
//never intercept because of different intercept.
return null;
}else{
//the two lines are overlaped each other, we pick one endpoint for return.
if ((x1>=Math.min(x3,x4) && x1<=Math.max(x3,x4)))
return new JFPoint(x1,y1);
else if
((x2>=Math.min(x3,x4) && x2<=Math.max(x3,x4)))
return new JFPoint(x2,y2);
}
}else if (slope1==0 && slope2==GeomConst.LARGE_VALUE){
if (x3>=Math.min(x1,x2) && x3<=Math.max(x1,x2) &&
y1>=Math.min(y3,y4) && y1<=Math.max(y3,y4)){
return new JFPoint(x3,y1);
}else{
return null;
}
}else if (slope1==GeomConst.LARGE_VALUE && slope2==0){
if (x1>=Math.min(x3,x4) && x1<=Math.max(x3,x4) &&
y3>=Math.min(y1,y2) && y3<=Math.max(y1,y2)){
return new JFPoint(x1,y3);
}else{
return null;
}
}else if (slope1==0 || slope1==GeomConst.LARGE_VALUE || slope2==0 || slope2==GeomConst.LARGE_VALUE){
double interx =0;
double intery =0;
if (slope1==0){
//from the equation y=k2(x-x3) + y3,(notice now y=y1) we got,
//x=(y1+ k2 * x3 -y3)/k2
interx = (y1 + slope2 * x3 - y3)/slope2;
intery = y1;
}else if (slope2==0){
//from the equation y=k1(x-x1) + y1,(notice now y=y3) we got,
//x=(y3+ k1 * x1 -y1)/k1
interx = (y3 + slope1 * x1 - y1)/slope1;
intery = y3;
}else if (slope1==GeomConst.LARGE_VALUE){
//from the equation y=k2(x-x3) + y3,(notice now x=x1) we got,
//y=k2(x1-x3) + y3
interx = x1;
intery = slope2 *(x1-x3) + y3;
}else if (slope2==GeomConst.LARGE_VALUE){
//from the equation y=k1(x-x1) + y1,(notice now x=x3) we got,
//y=k1(x3-x1) + y1
interx = x3;
intery = slope1 *(x3-x1) + y1;
}
JFPoint inter =new JFPoint(interx,intery);
if (inter.middleOf(x1,y1,x2,y2) && inter.middleOf(x3,y3,x4,y4))
return inter;
else
return null;
}
x =(intercept2-intercept1)/(slope1-slope2);
if ( x>=Math.min(x1,x2) && x<=Math.max(x1,x2) &&
x>=Math.min(x3,x4) && x<=Math.max(x3,x4)){
y =slope1 * x + intercept1;
return new JFPoint(x,y);
}else{
return null;
}
}
/**
* Convert this object to String
*
* @return An string represents the content of the object
*
*/
public String toString(){
StringBuffer buf =new StringBuffer();
buf.append(";x1="); buf.append(m_point1.getX());
buf.append(";y1="); buf.append(m_point1.getY());
buf.append(";x2="); buf.append(m_point2.getX());
buf.append(";y2="); buf.append(m_point2.getY());
return buf.toString();
}
/**
* Creates a new object of the same class and with the same contents as this object.
*
* @return A clone of this instance.
*
*/
public Object clone() throws CloneNotSupportedException{
try{
return new LineSeg(this);
}catch(Exception e){
throw new CloneNotSupportedException(e.getMessage());
}
}
/**
* Returns the hashcode for this Object.
*
* @return hash code for this Point2D.
*
*/
public int hashCode(){
long x1 =Double.doubleToLongBits(m_point1.getX());
long y1 =Double.doubleToLongBits(m_point1.getY());
long x2 =Double.doubleToLongBits(m_point2.getX());
long y2 =Double.doubleToLongBits(m_point2.getY());
return (int)(x1 ^ (x1 >>> 32)) ^ (int)(y1 ^ (y1 >>> 32)) ^
(int)(x2 ^ (x2 >>> 32)) ^ (int)(y2 ^ (y2 >>> 32))
;
}
/**
* Determines whether or not two objects are equal.
*
* @param obj an object to be compared with this object
*
* @return true if the object to be compared is an instance of Port and has the same values; false otherwise.
*
*/
public boolean equals(Object obj){
if (obj == this)
return true;
if (!(obj instanceof LineSeg))
return false;
LineSeg line =(LineSeg)obj;
return (m_point1.getX()==line.getX1()) && (m_point1.getY()==line.getY1()) &&
(m_point2.getX()==line.getX2()) && (m_point2.getY()==line.getY2())
;
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?