lineseg.java
来自「用Java开发的、实现类似Visio功能的应用程序源码」· Java 代码 · 共 1,182 行 · 第 1/3 页
JAVA
1,182 行
* Reverse this line by a central y coordinate of this line. We make a up-down flip here.
*/
public void flipBy(){
double centralY =(m_point1.getY() + m_point2.getY())/2;
flipBy(centralY);
}
/**
* Reverse this line by a y coordinate. We make a up-down flip here.
*
* @param baseY A flip base y coordinate.
*
*/
public void flipBy(double baseY){
m_point1.flipBy(baseY);
m_point2.flipBy(baseY);
}
/**
* Scale current rectangle by specified points and scale percent.
* We only support a concurrent width-height scale here, suppose width as the length from
* basePoint to refPoint1, height as the length from basePoint to refPoint2, and
* one scale percent acts on both width and height.
*
* @param basePoint A base point that is unmovable.
* @param refPoint1 A 'width' reference point.
* @param refPoint2 A 'height' reference point.
* @param scale A reference scale percent.
*
*/
public void scaleBy(JFPoint basePoint, JFPoint refPoint1, JFPoint refPoint2, double scale){
JFPoint center =getCenter();
m_point1.scaleBy(center.getX(),center.getY(),scale);
m_point2.scaleBy(center.getX(),center.getY(),scale);
JFPoint newCenter =Rect.newScaleCenter(center,basePoint,refPoint1,refPoint2,scale);
//move center
moveBy(newCenter.getX()-center.getX(),newCenter.getY()-center.getY());
}
/**
* Scale this line by its center point, and specified scale.
*
* @param scale A scale value.
*
*/
public void scaleBy(double scale){
JFPoint center =getCenter();
scaleBy(center.getX(),center.getY(),scale);
}
/**
* Scale this line by a point, and specified scale.
*
* @param baseX, baseY A scale reference point.
*
* @param scale A scale value.
*
*/
public void scaleBy(double baseX, double baseY, double scale){
scaleBy(baseX,baseY,scale,scale);
}
/**
* Scale this line by a point, and specified scale.
*
* @param baseX, baseY A scale reference point.
*
* @param xScale A scale value in x coordinate.
* @param yScale A scale value in y coordinate.
*
*/
public void scaleBy(double baseX, double baseY, double xScale, double yScale){
m_point1.scaleBy(baseX,baseY,xScale,yScale);
m_point2.scaleBy(baseX,baseY,xScale,yScale);
}
/**
* Test if a point is on this line.
*
* @param pnt A point to be measured.
*
* @return True if the point is on this line, false otherwise.
*
*/
public boolean contains(JFPoint pnt){
if (pnt==null)
return false;
else
return contains(pnt,0);
}
/**
* Test if a point is on this line.
* Here we used an analog offset for 'pick' this line.
*
* @param pnt A point to be measured.
*
* @param pickOffset An analog offset for 'pick' this line.
*
* @return True if the point is on this line, false otherwise.
*
*/
public boolean contains(JFPoint pnt,double pickOffset){
if (pnt==null)
return false;
else
return contains(pnt.getX(),pnt.getY(),pickOffset);
}
/**
* Test if a point(x, y coordinates for instead) is on this line.
* @param x X coordinate of this point.
*
* @param y Y coordinate of this point.
*
* @return True if the point is on this line, false otherwise.
*
*/
public boolean contains(double x, double y){
return contains(x,y,0);
}
/**
* Test if a point(x, y coordinates for instead) is on this line.
* Here we used an analog offset for 'pick' this line.
*
* @param x X coordinate of this point.
*
* @param y Y coordinate of this point.
*
* @return True if the point is on this line, false otherwise.
*
*/
public boolean contains(double x, double y,double pickOffset){
double dist = distance(x,y);
return ((float)dist<=pickOffset);
}
/**
* Test if three points are on same line.
*
* @param point1 first point one the line.
*
* @param point2 second point one the line
*
* @param point3 third point one the line
*
* @return True if the three points are on same line, False otherwise.
*
*/
public static boolean sameLinePoints(JFPoint point1, JFPoint point2, JFPoint point3){
if (point1==null || point2==null || point3==null)
return false;
return sameLinePoints(point1.getX(),point1.getY(),point2.getX(),point2.getY(),point3.getX(),point3.getY());
}
/**
* Test if three points are on same line.
*
* @param x1, y1 first point one the line.
*
* @param x2, y2 second point one the line
*
* @param x3, y3 third point one the line
*
* @return True if the three points are on same line, False otherwise.
*
*/
public static boolean sameLinePoints(double x1, double y1, double x2, double y2, double x3, double y3){
//on same vertical line
if ((float)x1==(float)x2 && (float)x2==(float)x3)
return true;
//on same horizontal line
else if ((float)y1==(float)y2 && (float)y2==(float)y3)
return true;
double slope1 =getSlope(x1,y1,x2,y2);
double slope2 =getSlope(x2,y2,x3,y3);
return (slope1==slope2);
}
/**
* Returns the distance from a point to this line segment.
* The distance measured is the distance between the specified
* point and the closest point between the specified endpoints.
* If the specified point is on the line segment, this method returns 0.0.
*
* @param pnt the specified point being
* measured against the specified line segment
*
* @return a double value that is the distance from the
* specified point to this line segment.
*/
public double distance(JFPoint pnt) {
return distance(pnt.getX(),pnt.getY());
}
/**
* Returns the distance from a point to this line segment.
* The distance measured is the distance between the specified
* point and the closest point between the specified endpoints.
* If the specified point is on the line segment, this method returns 0.0.
*
* @param px, py the coordinates of the specified point being
* measured against the specified line segment
*
* @return a double value that is the distance from the
* specified point to this line segment.
*/
public double distance(double px, double py) {
//get the closest point on this line to the specified point.
JFPoint closePnt =closeTo(px,py);
return closePnt.distance(px,py);
}
/**
* Returns a closest point on this line segment to specified point.
*
* @param px, py the coordinates of the specified point being
* measured against the specified line segment
*
* @return a point that is on this line segment and has a shortest distance
* to specified point.
*/
public JFPoint closeTo(double px, double py) {
double x1 =m_point1.getX();
double y1 =m_point1.getY();
double x2 =m_point2.getX();
double y2 =m_point2.getY();
JFPoint newPnt =null; //upright foot
//vertical line.
if ((float)x1==(float)x2){
newPnt =new JFPoint(x1,py);
//upright point is on the line segment:
if ((py>=y1 && py<=y2) || (py>=y2 && py<=y1)){
return newPnt;
//upright point is outside of the line segment,
//then choose the closest endpoint to upright point:
}else{
if (newPnt.distance(x1,y1)<newPnt.distance(x2,y2)){
return new JFPoint(x1,y1);
}else{
return new JFPoint(x2,y2);
}
}
//horizontal line
}else if ((float)y1==(float)y2){
newPnt =new JFPoint(px,y1);
//upright point is on the line segment:
if ((px>=x1 && px<=x2) || (px>=x2 && px<=x1)){
return newPnt;
//upright point is outside of the line segment,
//then choose the closest endpoint to upright point:
}else{
if (newPnt.distance(x1,y1)<newPnt.distance(x2,y2)){
return new JFPoint(x1,y1);
}else{
return new JFPoint(x2,y2);
}
}
//inclined/any line
}else{
/**
Inclined line should has a slope.
Assume we have two endpoints, pt1 and pt2,
slope k = ( pt2.y - pt1. y ) / (pt2.x - pt1.x );
equation of line is y = k* ( x - pt1.x) + pt1.y;
slope of upright line is -1/k
equation of upright line is y = (-1/k) * (x - point.x) + point.y
so we can get:
x = ( k^2 * pt1.x + k * (point.y - pt1.y ) + point.x ) / ( k^2 + 1),
y = k * ( x - pt1.x) + pt1.y;
*/
//slope of line.
double slope =( y2 - y1 ) / (x2 - x1 );
//x coordinate of upright point.
double x = (Math.pow(slope,2) * x1 + slope * (py - y1) + px)/(Math.pow(slope,2)+1);
double y = slope * (x - x1) + y1;
newPnt =new JFPoint(x,y);
//upright point is on the line segment:
if (((x>=x1 && x<=x2) || (x>=x2 && x<=x1))&&
((y>=y1 && y<=y2) || (y>=y2 && y<=y1))) {
return newPnt;
//upright point is outside of the line segment,
//then choose the closest endpoint to upright point:
}else{
if (newPnt.distance(x1,y1)<newPnt.distance(x2,y2)){
return new JFPoint(x1,y1);
}else{
return new JFPoint(x2,y2);
}
}
}
}
/**
* Returns an upright foot point on this line segment to specified point.
*
* @param px, py the coordinates of the specified point being
* measured against the specified line segment
*
* @return an upright foot point that is on this line segment or its extended line.
*/
public JFPoint uprightFoot(double px, double py) {
double x1 =m_point1.getX();
double y1 =m_point1.getY();
double x2 =m_point2.getX();
double y2 =m_point2.getY();
double slope=0;
//vertical line.
if ((float)x1==(float)x2){
slope =GeomConst.LARGE_VALUE;
//horizontal line
}else if ((float)y1==(float)y2){
slope =0;
//inclined/any line
}else{
/**
Inclined line should has a slope.
Assume we have two endpoints, pt1 and pt2,
slope k = ( pt2.y - pt1. y ) / (pt2.x - pt1.x );
*/
//slope of line.
slope =( y2 - y1 ) / (x2 - x1 );
}
return uprightFoot(slope,x1,y1,px,py);
}
/**
* Returns an upright foot point on a specified slope of a line accross a specified point.
* @param slope A slope of a line.
* @param x1, y1 the coordinates of a point the line accrosed.
* @param px, py the coordinates of the specified point being
* measured against the specified line segment
*
* @return an upright foot point that is on this line segment or its extended line.
*/
public static JFPoint uprightFoot(double slope, double x1, double y1, double px, double py) {
//vertical line.
if (slope==GeomConst.LARGE_VALUE){
return new JFPoint(x1,py);
//horizontal line
}else if (slope==0){
return new JFPoint(px,y1);
//inclined/any line
}else{
/**
Inclined line should has a slope.
Assume we have two endpoints, pt1 and pt2,
slope k = ( pt2.y - pt1. y ) / (pt2.x - pt1.x );
equation of line is y = k* ( x - pt1.x) + pt1.y;
slope of upright line is -1/k
equation of upright line is y = (-1/k) * (x - point.x) + point.y
so we can get:
x = ( k^2 * pt1.x + k * (point.y - pt1.y ) + point.x ) / ( k^2 + 1),
y = k * ( x - pt1.x) + pt1.y;
*/
//x coordinate of upright point.
double x = (Math.pow(slope,2) * x1 + slope * (py - y1) + px)/(Math.pow(slope,2)+1);
double y = slope * (x - x1) + y1;
return new JFPoint(x,y);
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?