2016-05-25 180 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