0

我正在将Skycons移植到 Android 并且我已经让它们中的大多数都在工作,除了月亮使用Canvas.arc带有逆时针参数的 HTML5。

我试图这样实现:

RectF rect = new RectF();

public void arcR( Path path, float x, float y, float radius, double startAngle, double endAngle, boolean anticlockwise ){
    // Set bounds
    rect.set( x - radius, y - radius, x + radius, y + radius );

    // Convert to degrees
    startAngle = Math.toDegrees(startAngle);
    endAngle = Math.toDegrees(endAngle);

    if(anticlockwise){
        startAngle = 360 - startAngle;
        endAngle = 360 - endAngle;
    }

    endAngle = endAngle - startAngle;

    path.addArc(rect, (float)startAngle, (float)endAngle);
}

我认为我没有正确实现逆时针,因为在我的设备上绘制月亮(基于 Skycons)看起来像这样:

截屏

4

4 回答 4

5

对于逆时针弧,扫角需要为负

float sweepAngle = ((endAngle + 360) - startAngle) % 360;
if (anticlockwise) {
  sweepAngle = sweepAngle - 360;
}
path.addArc(rect, startAngle, sweepAngle);
于 2013-09-03T19:15:58.737 回答
0
double sweepAngle = endAngle - startAngle;
startAngle = 360 - endAngle;
path.addArc(rect, (float)startAngle, (float)sweepAngle);
于 2013-08-29T18:01:55.680 回答
0

要绘制这样的切口线,您需要找到第二个圆的中心。我假设切割圆的半径与原始圆的半径相同,但当然你可以改变它。

请尝试以下代码:

private void drawMoon(Path path, float x, float y, float radius, float startAngle, float endAngle) {

  float sweepAngle = endAngle - startAngle;

  float x1 = (float) (x + radius * Math.cos(Math.toRadians(startAngle)));
  float y1 = (float) (y + radius * Math.sin(Math.toRadians(startAngle)));

  float x2 = (float) (x + radius * Math.cos(Math.toRadians(endAngle)));
  float y2 = (float) (y + radius * Math.sin(Math.toRadians(endAngle)));

  float x3 = (x1 + x2) / 2;
  float y3 = (y1 + y2) / 2;
  float q = (float) Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));

  float r = radius; // cutout circle radius
  float cx = (float) (x3 + Math.sqrt(r * r - (q / 2) * (q / 2)) * (y1 - y2) / q);
  float cy = (float) (y3 + Math.sqrt(r * r - (q / 2) * (q / 2)) * (x2 - x1) / q);

  path.rewind();

  rect.set(x - radius, y - radius, x + radius, y + radius);
  path.addArc(rect, startAngle, sweepAngle);

  rect.set(cx - r, cy - r, cx + r, cy + r);
  path.addArc(rect, (float) Math.toDegrees(Math.atan2(y1 - cy, x1 - cx)), 360 - sweepAngle);

}
于 2013-08-31T09:07:33.143 回答
0

html5 canvas arc和android canvas arc的区别:

  1. 在 html5/javascript 中,您将 centerX、centerY、radius 作为前 3 个参数。在 android 中,你用矩形包围圆圈而不是那些 3。这对圆圈来说有点麻烦,但更灵活,因为你也可以做椭圆(椭圆)

  2. 在 javascript 中,您将逆时针方向的起始角度、结束角度和布尔值作为参数 4、5、6。在 android 中,您改为给出起始角度和“扫描角度”。“扫掠角”是结束角和开始角之间的差。如果你想逆时针,只需给出一个负扫角。

  3. javascript角度以弧度为单位,在android中以度为单位。

作为说明,这里有一些示例代码绘制了一个 C 形图形,该图形由左侧的长弧和右侧的 3 个短弧组成,其中一个是逆时针的。

JavaScript:

<!DOCTYPE HTML>
<html>
    <head>
        <meta http-equiv="content-type" content="text/html" />
        <title>arcs</title>
        <script type="text/javascript">
function initPage(){
    ctx = document.getElementById("canvas").getContext('2d');
    ctx.fillStyle = "blue";
    pi = Math.PI;
    r = 100;
    R = 3 * r;
    padding = 5;
    width = 2 * (R + padding);
    height = width;
    centerX = padding + width/2;
    centerY = padding + height/2;
    ctx.beginPath();
    ctx.arc(centerX, centerY,       R,   pi/2, 3*pi/2, false);
    ctx.arc(centerX, centerY - 2*r, r, 3*pi/2,   pi/2, false);
    ctx.arc(centerX, centerY,       r, 3*pi/2,   pi/2, true );
    ctx.arc(centerX, centerY + 2*r, r, 3*pi/2,   pi/2, false);
    ctx.fill();
}
        </script>        
    </head>

    <body onload="initPage();">
        <canvas id="canvas" width="610" height="610"></canvas>
    </body>
</html>

安卓:

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.widget.ImageView;

public class MainActivity extends Activity {

    private void drawToImageView(ImageView iv){
        Paint paint = new Paint();
        paint.setStyle(Paint.Style.FILL);
        paint.setColor(Color.BLUE);
        Path path = new Path();
        int radius = 140;
        int Radius = 3 * radius;
        int padding = 5;
        int width = 2 * (Radius + padding);
        int height = width;
        Bitmap bm = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bm);
        float a = 90f;
        float b = 3*a;
        float pi = 2*a;
        float _radius = (float)radius;
        float _Radius = (float)Radius;
        float centerX = padding + width/2;
        float centerY = padding + height/2;
        path.addArc(circRect(centerX, centerY,             _Radius), a,  pi);
        path.addArc(circRect(centerX, centerY - 2*_radius, _radius), b,  pi);
        path.addArc(circRect(centerX, centerY,             _radius), b, -pi);
        path.addArc(circRect(centerX, centerY + 2*_radius, _radius), b,  pi);
        canvas.drawPath(path, paint);
        iv.setImageDrawable(new BitmapDrawable(getResources(), bm));
    }
    private RectF circRect(float centerX, float centerY, float radius){
        float left   = centerX - radius;
        float right  = centerX + radius;
        float top    = centerY - radius;
        float bottom = centerY + radius;
        return new RectF(left, top, right, bottom);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        ImageView iv = (ImageView)findViewById(R.id.myImageView);
        drawToImageView(iv);
    }
}
于 2015-01-10T12:04:09.340 回答