📄 curve.java
字号:
* @param x3,y3 A second control point of a bezier curve.
* @param x4,y4 An end point of a bezier curve.
* @param interval A time interval on this curve.
* @return The point on the curve.
*
*/
public static JFPoint getPoint(
double x1,double y1,
double x2, double y2,
double x3, double y3,
double x4, double y4,
double interval){
if (interval<0 || interval>1)
return null;
if (interval==0)
return new JFPoint(x1,y1);
if (interval==1)
return new JFPoint(x4,y4);
double t=interval; //the time interval
//use Bernstein polynomials
double x=(x1+t*(-x1*3+t*(3*x1-x1*t)))+
t*(3*x2+t*(-6*x2+ x2*3*t))+t*t*(x3*3-x3*3*t)+
x4*t*t*t;
double y=(y1+t*(-y1*3+t*(3*y1-y1*t)))+
t*(3*y2+t*(-6*y2+ y2*3*t))+t*t*(y3*3-y3*3*t)+
y4*t*t*t;
return new JFPoint(x,y);
}
/**
* Tests if the specified line intersects this curve.
*
* @param line The specified line segment.
*
* @return <code>true</code> if the specified line segment intersects the curve of this curve.
* false otherwise.
*/
public boolean intersects(LineSeg line) {
if (line==null)
return false;
return intersects(line.getX1(),line.getY1(),line.getX2(),line.getY2());
}
/**
* Get an intersected point both on this curve 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 curve and a new line.
*
* @param X1, Y1 the start point of line.
* @param X2, Y2 the end point of line.
* @return a intersected point, null if no interception.
*/
public JFPoint intersectsAt(double X1, double Y1, double X2, double Y2) {
double startX, startY, endX, endY;
LineSeg line=new LineSeg();
double x1 =getX1();
double y1 =getY1();
double x2 =getX2();
double y2 =getY2();
double x3 =getX3();
double y3 =getY3();
double x4 =getX4();
double y4 =getY4();
//start to test point on the whole outline of curve.
startX =x1;
startY =y1;
double t; //the time interval
double k = .025; //time step value for drawing curve
for(t=k;t<=1+k;t+=k){
//use Bernstein polynomials
endX=(x1+t*(-x1*3+t*(3*x1-x1*t)))+
t*(3*x2+t*(-6*x2+ x2*3*t))+t*t*(x3*3-x3*3*t)+
x4*t*t*t;
endY=(y1+t*(-y1*3+t*(3*y1-y1*t)))+
t*(3*y2+t*(-6*y2+ y2*3*t))+t*t*(y3*3-y3*3*t)+
y4*t*t*t;
//SIMPLY test if this seperate line segment of curve intersects the specified line segment
line.setValue(startX,startY,endX,endY);
JFPoint pnt =line.intersectsAt(X1,Y1,X2,Y2);
if (pnt!=null)
return pnt;
startX =endX;
startY =endY;
}
return null;
}
/**
* Tests if the specified line intersects this curve.
*
* @param X1, Y1 the start point of line.
*
* @param X2, Y2 the end point of line.
*
* @return <code>true</code> if the specified line segment intersects the curve of this curve.
* false 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>Curve</code>.
* @param rect the specified {@link Rect} to test for intersection
* with the interior of this <code>Curve</code>
* @return <code>true</code> if the specified <code>Rect</code>
* intersects the interior of this <code>Curve</code>;
* <code>false</code> otherwise.
*/
public boolean intersects(Rect rect) {
if (rect==null)
return false;
for (int i=Rect.SIDETYPE_LEFT; i<=Rect.SIDETYPE_BOTTOM; i++){
LineSeg side=rect.getSide(i);
if (intersects(side))
return true;
}
//test if current bezier curve is inside the target rectangle.
return rect.contains(getCenter());
}
/**
* 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();
if (scale<0) scale =0;
m_startPoint.scaleBy(center.getX(),center.getY(),scale);
m_controlPoint1.scaleBy(center.getX(),center.getY(),scale);
m_controlPoint2.scaleBy(center.getX(),center.getY(),scale);
m_endPoint.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 current object by a specified x and y scale.<br>
* This is a special scale method used to scale a shape in arbitrary x and y scale.<br>
* Please see AbstractShape.scaleBy for detailed description.
*
* @param basePoint A base scale point for scaling reference.
* @param xScale A scale percentage in x coordinate, default to 1.0
* @param yScale A scale percentage in y coordinate, default to 1.0
*
*/
public void scaleBy(JFPoint basePoint,double xScale, double yScale){
if (basePoint==null)
return;
double x =basePoint.getX();
double y =basePoint.getY();
m_startPoint.scaleBy(x,y,xScale,yScale);
m_controlPoint1.scaleBy(x,y,xScale,yScale);
m_controlPoint2.scaleBy(x,y,xScale,yScale);
m_endPoint.scaleBy(x,y,xScale,yScale);
}
/**
* Move this curve by specific x and y coordinates.
*
* @param x X coordiate to moveby.
*
* @param y Y coordiate to moveby.
*
*/
public void moveBy(double x, double y){
m_startPoint.moveBy(x,y);
m_controlPoint1.moveBy(x,y);
m_controlPoint2.moveBy(x,y);
m_endPoint.moveBy(x,y);
}
/**
* Rotate this curve by an angle theta.
*
* @param theta A rotate angle.
*
*/
public void rotateBy(double theta){
//get center point of this curve.
JFPoint center =getCenter();
//rotate by center
rotateBy(center,theta);
}
/**
* Rotate this curve by a specified point and an angle theta.
*
* @param pnt A rotate center point.
*
* @param theta A rotate angle.
*
*/
public void rotateBy(JFPoint pnt, double theta){
if (pnt!=null)
rotateBy(pnt.getX(),pnt.getY(),theta);
}
/**
* Rotate this curve by a specified point and an angle theta.
*
* @param baseX, baseY A rotate center point.
*
* @param theta A rotate angle.
*
*/
public void rotateBy(double baseX, double baseY, double theta){
m_startPoint.rotateBy(baseX,baseY,theta);
m_controlPoint1.rotateBy(baseX,baseY,theta);
m_controlPoint2.rotateBy(baseX,baseY,theta);
m_endPoint.rotateBy(baseX,baseY,theta);
}
/**
* Mirror this curve by a central x coordinate of this curve. We make a up-down flip here.
*/
public void mirrorBy(){
JFPoint center =getCenter();
mirrorBy(center.getX());
}
/**
* Mirror this curve by a x coordinate. We make a left-right mirror here.
*
* @param baseX A mirror base x coordinate.
*
*/
public void mirrorBy(double baseX){
m_startPoint.mirrorBy(baseX);
m_controlPoint1.mirrorBy(baseX);
m_controlPoint2.mirrorBy(baseX);
m_endPoint.mirrorBy(baseX);
}
/**
* Reverse this curve by a central y coordinate of this curve. We make a up-down flip here.
*/
public void flipBy(){
JFPoint center =getCenter();
flipBy(center.getY());
}
/**
* Reverse this curve by a y coordinate. We make a up-down flip here.
*
* @param baseY A flip base y coordinate.
*
*/
public void flipBy(double baseY){
m_startPoint.flipBy(baseY);
m_controlPoint1.flipBy(baseY);
m_controlPoint2.flipBy(baseY);
m_endPoint.flipBy(baseY);
}
/**
* Convert this object to String
*
* @return An string represents the content of the object
*
*/
public String toString(){
StringBuffer buf =new StringBuffer();
buf.append(";startPoint["); buf.append(m_startPoint.toString()); buf.append("]");
buf.append(";controlPoint1["); buf.append(m_controlPoint1.toString()); buf.append("]");
buf.append(";controlPoint2["); buf.append(m_controlPoint2.toString()); buf.append("]");
buf.append(";endPoint["); buf.append(m_endPoint.toString()); buf.append("]");
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 Curve(this);
}catch(Exception e){
throw new CloneNotSupportedException(e.getMessage());
}
}
/**
* Returns the hashcode for this Object.
*
* @return hash code for this Point2D.
*
*/
public int hashCode(){
return m_startPoint.hashCode() ^
m_controlPoint1.hashCode() ^
m_controlPoint2.hashCode() ^
m_endPoint.hashCode();
}
/**
* 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 Curve))
return false;
Curve curve =(Curve)obj;
return (m_startPoint.equals(curve.m_startPoint)) &&
(m_controlPoint1.equals(curve.m_controlPoint1)) &&
(m_controlPoint2.equals(curve.m_controlPoint2)) &&
(m_endPoint.equals(curve.m_endPoint));
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -