【问题标题】:How to draw ellipse's arc on android?如何在android上绘制椭圆的弧?
【发布时间】:2013-06-02 08:43:17
【问题描述】:

我想在我的 Android 应用程序中绘制一条椭圆弧。 我使用了这段代码:

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.save();
        angle=45; //angle of ellipse major axis with X-axis.
        startAngle=0; //start angle of arc
        sweepAngle=90; //sweep angle of arc
        a = 200; //major axis of ellipse
        b = 100; //minor axis of ellipse
        
        canvas.rotate(angle, center.x, center.y);
        //draw the arc
        canvas.drawArc(rect, startAngle - angle, sweepAngle, true, paintLine);

        paintLine.setPathEffect(new DashPathEffect(new float[] { 5, 5 }, 0));
        canvas.drawOval(rect, paintLine);

        canvas.restore();
        paintLine.setPathEffect(null);
    }

我收到这个形状:

我需要的弧线应该在这张图片的红点开始和结束:

请告诉我我犯了什么错误。

谢谢。

【问题讨论】:

  • 如果我理解正确的话,你必须将角度设置为 90 而不是 45。一个圆由 360 度组成,四分之一是 90 度。如果要画 90 度,角度必须是 90 度。将 startAngle 设置为 0 表示从 3 点开始绘制。如果你想在 6 点钟开始绘图,你必须设置 0 - 90。所以 startAngle=0;角度=90;如果我猜对了,我会把它设置为答案
  • @Opiatefuchs,angle 是椭圆与 X 轴的角度。如果我设置angle = 90,则椭圆的长轴将在verticle处绘制,然后Arc将有另一个外观。
  • 好的,然后在 drawArc 方法中为 startAngle 设置新值。例如 float startValue = -90;仅用于测试我是否正确......
  • 当我为drawArc 方法设置-90 时,起点将在红线上方。请注意,这个问题只发生在椭圆形上,圆形一切正常。
  • 对于遇到此线程的任何人...请不要在您的 onDraw 方法中使用此行 paintLine.setPathEffect(new DashPathEffect(new float[] { 5, 5 }, 0)); 您最好创建 2 个绘画对象。

标签: android canvas shape


【解决方案1】:

当 android 绘制椭圆弧时,就好像它首先在提供的扫角上绘制圆弧一样。然后它缩放这个圆弧,使其适合指定的椭圆。椭圆的起始角和后掠角将不同于指定的起始角和后掠角。要获得想要的角度,必须将实际角度指定为 tan(actual-angle) = (a/b)*tan(wanted-angle)

public class Main3Activity extends Activity {
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    View view = new View(this) {
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            canvas.save();
            float angle=45; //angle of ellipse major axis with X-axis.
            // These are the wanted angles
            float startAngle_ = (float)Math.toRadians(315); //start angle of arc
            float endAngle_ = (float)Math.toRadians(45); //end angle of arc
            float a = 200; //major axis of ellipse
            float b = 100; //minor axis of ellipse
            float xc = getWidth()/2f;
            float yc = getHeight()/2f;

            // These are the angles to use
            float startAngle = (float)Math.toDegrees(
                            Math.atan2(a*Math.sin(startAngle_),b*Math.cos(startAngle_)));
            float endAngle = (float)Math.toDegrees(
                    Math.atan2(a*Math.sin(endAngle_),b*Math.cos(endAngle_)));
            float sweepAngle = endAngle - startAngle;

            RectF rect = new RectF(xc-a,yc-b,xc+a,yc+b);
            Paint paintLine = new Paint(Paint.ANTI_ALIAS_FLAG);
            paintLine.setStyle(Paint.Style.STROKE);

            canvas.rotate(angle,xc,yc);
            //draw the arc
            canvas.drawArc(rect, startAngle, sweepAngle, true, paintLine);

            paintLine.setPathEffect(new DashPathEffect(new float[] { 5, 5 }, 0));
            canvas.drawOval(rect, paintLine);

            canvas.restore();
            paintLine.setPathEffect(null);
        }
    };

    FrameLayout.LayoutParams layout = new FrameLayout.LayoutParams(
            ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);

    addContentView(view,layout);
}

这个问题已经快七年了!是时候更新文档了吗?

【讨论】:

    最近更新 更多