在安卓平台上,当起始角度大于结束角度时,drawArc函数无法正确绘制弧形。

4
我正在尝试使用触摸监听器在圆形内的两个点之间绘制弧线。以下是我的代码:

public class MainActivity extends Activity implements OnTouchListener {

ImageView whiteCircle, centreCircle, slideArcFrame;
int xStart = 0, yStart = 0, xEnd = 0, yEnd = 0, centerIx = 0, centerIy = 0;
Bitmap output;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    whiteCircle = (ImageView) findViewById(R.id.centerImageWhite);
    centreCircle = (ImageView) findViewById(R.id.centerImage2);
    slideArcFrame = (ImageView) findViewById(R.id.centerImage);
    slideArcFrame.setOnTouchListener(this);
    slideArcFrame.setDrawingCacheEnabled(true);
    slideArcFrame.measure(
            MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
            MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
    slideArcFrame.layout(0, 0, slideArcFrame.getMeasuredWidth(),
            slideArcFrame.getMeasuredHeight());
    slideArcFrame.buildDrawingCache(true);
    output = Bitmap.createBitmap(slideArcFrame.getDrawingCache());
    centerIx = 100;
    centerIy = 100;
}

@Override
public boolean onTouch(View arg0, MotionEvent arg1) {
    if (arg1.getAction() == MotionEvent.ACTION_DOWN) {
        xStart = (int) arg1.getX();
        yStart = (int) arg1.getY();
    }
    if (arg1.getAction() == MotionEvent.ACTION_MOVE) {
        xEnd = (int) arg1.getX();
        yEnd = (int) arg1.getY();
        drawArc();
    }
    if (arg1.getAction() == MotionEvent.ACTION_UP) {
        xEnd = (int) arg1.getX();
        yEnd = (int) arg1.getY();
    }
    return true;
}

private void drawArc() {
    Bitmap outp = Bitmap.createBitmap(output.getWidth(),
            output.getHeight(), Config.ARGB_8888);
    Canvas can = new Canvas(outp);
    final Paint paint = new Paint();
    RectF rect = new RectF(0, 0, output.getWidth(), output.getHeight());
    can.drawARGB(0, 0, 0, 0);
    paint.setAntiAlias(true);
    paint.setColor(getResources().getColor(R.color.white));
    double quadXS, quadYS, quadXE, quadYE;
    double quadrantS = 0, quadrantE = 0;
    quadXS = xStart - centerIx;
    quadYS = yStart - centerIy;
    quadXE = xEnd - centerIx;
    quadYE = yEnd - centerIy;
    if (quadXS >= 0 && quadYS >= 0)
        quadrantS = 1;
    if (quadXS < 0 && quadYS >= 0)
        quadrantS = 2;
    if (quadXS < 0 && quadYS < 0)
        quadrantS = 3;
    if (quadXS >= 0 && quadYS < 0)
        quadrantS = 4;
    if (quadXE >= 0 && quadYE >= 0)
        quadrantE = 1;
    if (quadXE < 0 && quadYE >= 0)
        quadrantE = 2;
    if (quadXE < 0 && quadYE < 0)
        quadrantE = 3;
    if (quadXE >= 0 && quadYE < 0)
        quadrantE = 4;
    double startAngle = 0, endAngle = 0;
    if (quadrantS == 1) {
        startAngle = Math.toDegrees(Math.atan((double) (quadYS) / quadXS));
    }
    if (quadrantS == 2) {
        startAngle = 180 - Math.toDegrees(Math.atan((double) (quadYS)
                / -quadXS));
    }
    if (quadrantS == 3) {
        startAngle = 180 + Math.toDegrees(Math.atan((double) (-quadYS)
                / -quadXS));
    }
    if (quadrantS == 4) {
        startAngle = 360 - Math.toDegrees(Math.atan((double) (-quadYS)
                / quadXS));
    }
    if (quadrantE == 1) {
        endAngle = Math.toDegrees(Math.atan((double) (quadYE) / quadXE));
    }
    if (quadrantE == 2) {
        endAngle = 180 - Math.toDegrees(Math.atan((double) (quadYE)
                / -quadXE));
    }
    if (quadrantE == 3) {
        endAngle = 180 + Math.toDegrees(Math.atan((double) (-quadYE)
                / -quadXE));
    }
    if (quadrantE == 4) {
        endAngle = 360 - Math.toDegrees(Math.atan((double) (-quadYE)
                / quadXE));
    }
    can.drawArc(rect, (float) startAngle, (float) endAngle
            - (float) startAngle, true, paint);
    slideArcFrame.setImageBitmap(outp);
}
}

当起始角度大于结束角度时,弧形将从结束角度绘制到起始角度。请问有人可以解释一下吗?
1个回答

3
对于`sweepAngle`,您正在使用`endAngle - startAngle`。如果`startAngle`更高,它最终会成为负数。
文档中提到
引用:

如果扫描角度是负数,则将扫描角度视为扫描角度模360。

......

圆弧顺时针绘制。

问题在于,Java可以用模运算返回负数, 因此`-30 mod 360 = -30`。 对于负度数,它会逆时针绘制。 如果您希望始终以顺时针方式绘制,请向其提供正数:
float sweepAngle = endAngle - startAngle;
while(sweepAngle < 0)
    sweepAngle += 360;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接