将quardrative曲线转换为多边形链

时间:2015-09-06 05:41:18

标签: java geometry

我使用html5画布及其绘制正确绘制了一个quardrativecurve。我在这里附加输出图像

enter image description here

绘制此曲线的代码

var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
ctx.beginPath();
ctx.moveTo(20,20);
ctx.quadraticCurveTo(20,100,200,20);
ctx.stroke();

但是现在我想把这个quardrative曲线分成直线数表示使用java的点数。我怎样才能做到这一点?请帮帮我。

3 个答案:

答案 0 :(得分:1)

您可以使用以下代码将二次分割成多行。要将二次曲线分成多行,您只需要遵循以下信息

1)二次曲线的起点

2)二次曲线的控制点。

3)二次曲线的终点。

    List<Coordinate> coordinates = new ArrayList<Coordinate>();
    Coordinate startPoint = QuadraticCurveTo.getStartPoint();        
    Coordinate controlPoint = QuadraticCurveTo.getControlPoint();    
    Coordinate endPoint_ = QuadraticCurveTo.getEndPoint();

    double s  = 0;
    double t = 1;

    while (s < t) {
      s += 0.1; 
      double controlParameter = (1 - s);
      Coordinate Q_0 = new Coordinate(controlParameter * startPoint.getX(), controlParameter * startPoint.getY()).offset(new Coordinate(s * controlPoint.getX(), s * controlPoint.getY()));          
      Coordinate Q_1 = new Coordinate(controlParameter * controlPoint.getX(), controlParameter * controlPoint.getY()).offset(new Coordinate(s * endPoint_.getX(), s * endPoint_.getY()));
      Coordinate R_0 = new Coordinate(controlParameter * Q_0.getX(), controlParameter * Q_0.getY()).offset(new Coordinate(s * Q_1.getX(), s * Q_1.getY()));
      coordinates.add(R_0);
    }

答案 1 :(得分:0)

你有二次贝塞尔曲线。可以将曲线划分为两条较小的曲线并重复此过程,直到曲线段足够平坦以由线段表示。此过程称为递归细分。对于二次曲线,它很简单:

初始曲线B,控制点P0,P1,P2
新曲线B&#39;和B&#39;&#39;有控制点

P0' = P0
P1' = 1/2 * (P1 - P0)
P2' = 1/2 * P1 + 1/4 * (P0 + P2)    //correction here

P0'' = P2'  //cut point of subdivision
P1'' = 1/2 * (P2 - P1)
P2'' = P2

可以通过三角形P0P1P2的面积除以P0P2的平方范围(欧几里德或曼哈顿距离)来估计曲线平坦度。

BTW,Windows GDI有方法FlattenPath,它将曲线转换为线段序列。可能,FlatteningPathIterator或其他Java方法也会做同样的伎俩

答案 2 :(得分:0)

因此在Java中,似乎有一个内置函数使用PathIterator将Quadratic曲线拆分为线段。这是要点:

//Create a quadratic curve
double x1 = lineInfo[1];
double y1 = lineInfo[2];
double cx = lineInfo[3]; //spline control point
double cy = lineInfo[4]; //spline control point
double x2 = lineInfo[5];
double y2 = lineInfo[6];
QuadCurve2D quadCurve = new QuadCurve2D.Double(x1, y1, cx, cy, x2, y2);


//Split the curve into line strings - adjust the tolerance as needed (e.g. 0.5)
ArrayList<double[]> coordinates = new ArrayList<>();
PathIterator it = quadCurve.getPathIterator(null, 0.5);
while (!it.isDone()){
    double[] coords = new double[2];
    it.currentSegment(coords);
    coordinates.add(coords);
    it.next();
}

//Draw line segments to verify
for (int i=1; i<coordinates.size(); i++){
    double[] prevCoord = coordinates.get(i-1);
    double[] currCoord = coordinates.get(i);
    int x1 = (int) Math.round(prevCoord[0]);
    int y1 = (int) Math.round(prevCoord[1]);
    int x2 = (int) Math.round(currCoord[0]);
    int y2 = (int) Math.round(currCoord[1]);
    g2.drawLine(x1, y1, x2, y2);
}