当startAngle> drawArc没有正确绘制android中的endAngle

时间:2013-11-08 16:06:51

标签: android

我正在尝试使用触摸侦听器在圆圈中的两个点之间绘制圆弧。这是我的代码:

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 个答案:

答案 0 :(得分:3)

对于sweepAngle,您使用的是endAngle - startAngle。如果startAngle更高,则会以负数结束。

The docs这样说:

  

如果扫掠角度为负,则将扫掠角度视为模数360的扫掠角度。

     

...

     

顺时针绘制弧线。

事情是Java can return negative numbers with modulus,所以-30 mod 360 = -30。 对于负度,它将逆时针绘制。如果你希望它总是顺时针绘制,你需要给它一个正数:

float sweepAngle = endAngle - startAngle;
while(sweepAngle < 0)
    sweepAngle += 360;