Android   发布时间:2022-04-28  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了android – 垂直轴的旋转角度大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我目前正在尝试创建一个可以在填充百分比中调整的仪表.我遇到的问题是我根本不擅长数学.我想开始在’北'(第一张图像)中画一条弧,而不是在’东’中有一个0度点的普通弧(如第二张图所示).

我希望能够通过沿着屏幕拖动/触摸来增加图像1中蓝色区域的大小(角度).现在这些是我现在能以某种方式做的事情.我面临的真正问题是:

我使用以下代码绘制蓝色区域:

@H_8_11@mStart = -90; int degree = (int)((theta + Math.PI) * 180 / Math.PI); mSweep = degree; RectF mOvals = new RectF(c.x - outerRadius + circleThickness,c.y - outerRadius + circleThickness,c.x + outerRadius - circleThickness,c.y + outerRadius - circleThickness ); mArcSetLevel = new Path(); if(mArcSetLevel != null ) { canvas.drawArc(mOvals,mStart,mSweep,true,arcPaint); }

将起点设置为-90使其提前90度开始.为了跟踪触摸的角度,我使用这个公式,但这是出错的地方:

int py = (int)event.getY() - c.y;
int px = (int)event.getX() - c.x;

theta = (float) ((float)  Math.atan2(py,pX) - (Math.PI / 2)); // - Math.PI / 2 to correct -90 start

当我进一步超过270度时,蓝色区域会被重置,并以更小的角度从北向西拉伸(因为-90的’假’开始,如第三张图所示).我的数学技能根本不足以让我能够解决这个问题,然我能想到为什么会发生这种情况我似乎无法找到解决方案.

我做的整个视图的(非常混乱的)代码如下:

private Canvas canvas;  

//Canvas width and height
privatE int h = -1;
privatE int w = -1;

//circle properties
private Paint paint;
private Paint arcPaint;
private Path circle;
private Point c;
privatE int outerRadius;
privatE int circleThickness = 20;

//point click in wheel
private float theta = 0;

private float mStart;
private float mSweep;
private Paint mBgPaints   = new Paint();
private Path mArcSetLevel;

int padding = 10;

OnMeterWheelchangelistener onMeterWheelchangelistener = null;

public MeterWheel(Context context){
    super(context);
    initCircleSeekBar();
}

public MeterWheel(Context context,AttributeSet attrs) {
    super(context,attrs);
    initCircleSeekBar();
}

private void initCircleSeekBar() {

    canvas = new Canvas();
    circle = new Path();
    paint = new Paint();
    arcPaint = new Paint();
    c = new Point();

    mBgPaints.setAntiAlias(true);
    mBgPaints.setStyle(Paint.Style.FILL);
    mBgPaints.setColor(0x88FF0000);
    mBgPaints.setstrokeWidth(0.5f);

    mArcSetLevel = new Path();

    this.draw(canvas);
}


@Override
protected void onSizeChanged(int width,int height,int oldw,int oldh) {
    // TODO Auto-generated method stub
    super.onSizeChanged(width,height,oldw,oldh);

    w = width;
    h = height;
    Log.i("POWERWHEEL",String.valueOf(w) + "   " + String.valueOf(h));
    c.set(w/2,h/2);
    drawCircle();
}

private void drawCircle() {
    outerRadius = Math.min(h,w)/2;
    circleThickness = (int) (outerRadius*0.15);

    circle.addArc(new RectF(c.x - outerRadius + circleThickness/2,c.y - outerRadius + circleThickness/2,c.x + outerRadius - circleThickness/2,c.y + outerRadius - circleThickness/2 ),360);
    circle.moveTo(c.x,c.y);
    //paint.setShader(new SweepGradient(w/2,h/2,colourarry,null));
    paint.setColor(Color.GRAY);
    paint.setStyle(Style.stroke);
    paint.setstrokeWidth(circleThickness);
    paint.setAntiAlias(true);

    arcPaint.setColor(Color.bLUE);
    arcPaint.setStyle(Style.FILL);
    arcPaint.setstrokeWidth(circleThickness);
    arcPaint.setAntiAlias(true);
}


@SuppressLint("DrawAlLOCATIOn")
@Override
protected void onDraw(Canvas canvas) {
    // TODO Auto-generated method stub
    super.onDraw(canvas);

    if(circle != null){
    //draw circle
        canvas.drawPath(circle,paint);

        mStart = -90;

        int degree = (int)((theta + Math.PI) * 180 / Math.PI);
        Log.d("POWERWHEEL","" + degreE);
        mSweep = degree;

        RectF mOvals = new RectF(c.x - outerRadius + circleThickness,c.y + outerRadius - circleThickness );

        mArcSetLevel = new Path();

        if(mArcSetLevel != null ) {
            canvas.drawArc(mOvals,arcPaint);
        }
    }

}


@Override
public Boolean onTouchEvent(MotionEvent event) {

    if (!isEnabled()) {
        return false;
    }

    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            setPressed(true);
            onStartTrackingTouch(event);
            trackTouchEvent(event);
            break;

        case MotionEvent.ACTION_MOVE:
            trackTouchEvent(event);
            break;

        case MotionEvent.ACTION_UP:
            trackTouchEvent(event);
            onStopTrackingTouch();
            setPressed(false);
            invalidate();
            break;

        case MotionEvent.ACTION_CANCEL:
            onStopTrackingTouch();
            setPressed(false);
            invalidate();
            break;
    }

    return true;
}

@Override
protected void onMeasure(int widthMeasureSpec,int heightMeasureSpeC) {

    int width = MeasureSpec.getSize(widthMeasureSpec);
    int height = MeasureSpec.getSize(heightMeasureSpec);

    setMeasuredDimension(width,height);
}

private void onStartTrackingTouch(MotionEvent event) {

}

private void onStopTrackingTouch() {

}

private void trackTouchEvent(MotionEvent event) {

    int py = (int)event.getY() - c.y;
    int px = (int)event.getX() - c.x;

    theta = (float) ((float)  Math.atan2(py,pX) - (Math.PI / 2));
    Log.d("POWERWHEEL","theta: " + theta);

    this.invalidate();
}



public void setSize(int x,int y){
    h = y;
    w = x;
}

public void setCirleThickness(int t){
    circleThickness = t;
}


public void setOnMeterWheelchangelistener (OnMeterWheelchangelistener listener) {
    onMeterWheelchangelistener = listener;
}

public interface OnMeterWheelchangelistener{
    public void onStartTrackingTouch (MeterWheel colourWheel);
    public void onStopTrackingTouch (MeterWheel colourWheel);
}

提前一百万!

解决方法

计算theta时,使用atan2返回/ – pi中的角度.因此,当处于左上象限时,它将返回-pi / 2到-pi范围内的值(假设y是向下正向,x是向右正向).直接减去pi / 2,给出-pi到-3pi / 2的范围.在onDraw中,然后再次@L_944_22@pi(令人困惑),为此象限提供0到-pi / 2的扫描范围.这意味着它将从顶部的起始位置逆时针绘制弧0至pi / 2(或0至90度).您必须确保扫描始终保持在0到pi的范围内.最好的解决方案是将坐标移动-pi / 2,这样代替Math.atan2(py,pX),你可以执行Math.atan2(px,-py),然后如果θ为负,则@L_944_22@2 * pi.像(我不写android)的东西

theta = (float)  Math.atan2(px,-py);
if (theta < 0) theta += 2 * Math.PI;

然后在onDraw上

int degree = (int)(theta * 180 / Math.PI);
Log.d("POWERWHEEL","" + degreE);
mSweep = degree;

如果您仍然遇到问题,请检查mSweep是否始终在0到360度范围内.

大佬总结

以上是大佬教程为你收集整理的android – 垂直轴的旋转角度全部内容,希望文章能够帮你解决android – 垂直轴的旋转角度所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。