2016-05-25 105 views
2

我已经尝试了很多不同的方法从网络上的例子,但我似乎无法得到这个工作。
我正在试图制作一种在画布上绘制2点之间的曲线的方法。
曲线应该由半径参数定义。如何在画布上绘制2点之间的曲线?

下面是我目前的代码。

public OverlayBuilder drawCurvedArrow(int startX, int startY, int endX, int endY, int curveRadius, int padding, int color) { 
    PointF mPoint1 = new PointF(startX, startY); 
    PointF mPoint2 = new PointF(endX, endY); 
    Paint paint = new Paint(); 
    paint.setAntiAlias(true); 
    paint.setStyle(Paint.Style.STROKE); 
    paint.setStrokeWidth(12); 
    paint.setColor(color); 
    Path myPath = new Path(); 

    myPath.moveTo(startX, startY); 
    myPath.quadTo(mPoint1.x, mPoint1.y, mPoint2.x, mPoint2.y); 
    canvas.drawPath(myPath, paint); 

    return this; 
} 

编辑: 的问题是,我无法弄清楚如何曲线是在画布上绘制的线条。

我真的希望有人能帮助我解决这个问题。
任何帮助将不胜感激。

+0

尝试'帆布.drawArc()'。 –

+0

你的意思是说你想在两点之间画一个弧? –

回答

9

我自己找到了我的问题的解决方案。尽管有一些很好的答案,但它们并不是我的特殊问题的确切解决方案。

这里是我所做的:

  • 实测值的点在2个给定的点之间
  • 计算的角度的2点之间的90度
  • 计算从中间点的像素使用点X从之前计算的程度。
  • 使用这3点的“path.cubicTo”(同时使用负值和正值来确定线应该弯曲的方式)。

这里是我的代码,如果任何人都应该遇到了同样的问题:

public OverlayBuilder drawCurvedArrow(int x1, int y1, int x2, int y2, int curveRadius, int color, int lineWidth) { 

    Paint paint = new Paint(); 
    paint.setAntiAlias(true); 
    paint.setStyle(Paint.Style.STROKE); 
    paint.setStrokeWidth(lineWidth); 
    paint.setColor(ContextCompat.getColor(context, color)); 

    final Path path = new Path(); 
    int midX   = x1 + ((x2 - x1)/2); 
    int midY   = y1 + ((y2 - y1)/2); 
    float xDiff   = midX - x1; 
    float yDiff   = midY - y1; 
    double angle  = (Math.atan2(yDiff, xDiff) * (180/Math.PI)) - 90; 
    double angleRadians = Math.toRadians(angle); 
    float pointX  = (float) (midX + curveRadius * Math.cos(angleRadians)); 
    float pointY  = (float) (midY + curveRadius * Math.sin(angleRadians)); 

    path.moveTo(x1, y1); 
    path.cubicTo(x1,y1,pointX, pointY, x2, y2); 
    canvas.drawPath(path, paint); 

    return this; 
} 

这里是执行看起来像一个例子:

enter image description here

+0

嘿,什么是“OverlayBuilder”? –

+0

嘿! OverlayBuilder是一个类,它使用了构建器模式。在这种情况下,我用它来绘制和写视图的东西。 – Langkiller

+0

哇哇,我见过的最好的答案之一,谢谢 –

0

假设你有两个点mPoint1和mPoint2

int w=canvas.getWidth(); 
int h=canvas.getHeight(); 
int w_2= (w/2); 
int h_2= (h/2); 
PointF mPoint1 = new PointF(0, 0); //starts at canvas left top 
PointF mPoint2 = new PointF(w_2, h_2);//mid of the canvas 
Path drawPath1 =drawCurve(mPoint1, mPoint2); 
canvas.drawPath(drawPath1, paint); 

方法画线

private Path drawCurve(PointF mPointa, PointF mPointb) { 
      Path myPath = new Path(); 
      myPath.moveTo(mPointa.x, mPointa.y); 
      final float x2 = (mPointb.x + mPointa.x)/3; 
      final float y2 = (mPointb.y + mPointa.y)/3; 
      myPath.quadTo(x2, y2, mPointb.x, mPointb.y); 
      return myPath; 
} 

enter image description here

+0

感谢您的答案@Stallion。在您提供的代码中,定义半径的值在哪里? – Langkiller

+0

我已经做了这么久回来,你可以尝试改变3不同的值(2,3或4)? (mPointb.x + mPointa.x)/ VARIABLE – Stallion

+0

我试过了。如果设置为2,它只是一条直线。如果设置为更高的值,则绘制尖锐的形状。 – Langkiller

0

我认为你正在使用错误的方法用于此目的,的一个我可以建议的solutions以下是

float radius = 20; 
final RectF oval = new RectF(); 
oval.set(point1.x - radius, point1.y - radius, point1.x + radius, point1.y+ radius); 
Path myPath = new Path(); 
myPath.arcTo(oval, startAngle, -(float) sweepAngle, true); 

和startAngle开始计算,你将需要

int startAngle = (int) (180/Math.PI * Math.atan2(point.y - point1.y, point.x - point1.x)); 

为sweapAngle你可以找到详细的描述here

+0

谢谢!我在另一篇文章中看到过这个例子。什么是sweepAngle?我应该计算它的值不知何故? – Langkiller

+0

检查更新到我的答案 –

+0

好吧我会研究一下..嗯在计算startAngle时,什么是变量点?什么是point1 int代码的第一个片段?哪一个是起点和终点? – Langkiller