-1

我有一个三角形图像,其一个边缘始终与圆的方向相同。该图像必须根据用户滑动/拖动来围绕圆圈移动。因此,它必须同时旋转(使其边缘与圆的方向相同)并同时围绕圆旋转。

如何实现这个功能?

更新:我的自定义视图如下:

public class ThermoView extends FrameLayout{

    private ImageView mThermoBgrd;
    private ImageView mCurTempArrow;
    public static final int THEMROSTAT_BACKGROUND = 0;
    public static final int THEMROSTAT_CURR_TEMP = 1;



    public ThermostatView(Context context, AttributeSet attrs) {
        super(context, attrs);

        mThermoBgrd = new ImageView(context);
        mThermoBgrd.setImageResource(R.drawable.circle_icon);

        addView(mThermoBgrd, ThermostatView.THEMROSTAT_BACKGROUND);


        mCurTempArrow = new ImageView(context);
        mCurTempArrow.setImageResource(R.drawable.ruler_triangle_icon);
        mCurTempArrow.setScaleType(ImageView.ScaleType.MATRIX);
        addView(mCurTempArrow, ThermostatView.THEMROSTAT_CURR_TEMP, new LayoutParams(50, 50));


    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right,
            int bottom) {
        super.onLayout(changed, left, top, right, bottom);

        int currTempHeight = mCurTempArrow.getMeasuredHeight();
        int currTempWidth = mCurTempArrow.getMeasuredWidth();


        int parentWidth = right - left;
        int parentHeight = bottom - top;
        int padding = currTempHeight;

        //We need square container for the circle.
        int containerLeft = padding;
        int containerTop = parentHeight - parentWidth + padding;
        int containerRight = parentWidth - padding;
        int containerBottom = parentHeight - padding;
        int containerWidth = containerRight - containerLeft;
        int containerHeight = containerBottom - containerTop;


        //place the arrow indicating current temperature
        int curTempLeft = containerRight - ((containerWidth/2) + currTempWidth/2);
        int curTempTop = containerTop - (currTempHeight/2);
        int curTempRight = curTempLeft + currTempWidth;
        int curTempBottom = curTempTop + currTempHeight;

        mCurTempArrow.layout(curTempLeft, curTempTop, curTempRight, curTempBottom);

    }
4

2 回答 2

3

试试这个(它使用路径而不是位图,但想法是一样的):

public class MyView extends View {

    private Paint mPaint;
    private Path mTriangle;
    private Path mCircle;
    private Matrix mMatrix;
    private float mAngle;

    public MyView(Context context) {
        super(context);
        mPaint = new Paint();
        mPaint.setStrokeWidth(10);
        mPaint.setStyle(Style.STROKE);

        mTriangle = new Path();
        mTriangle.moveTo(0, -21);
        mTriangle.lineTo(0, 21);
        mTriangle.lineTo(36, 0);
        mTriangle.close();

        mCircle = new Path();
        mCircle.addCircle(0, 0, 50, Direction.CW);

        mMatrix = new Matrix();
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float w2 = getWidth() / 2f;
        float h2 = getHeight() / 2f;
        mAngle = (float) (180 * Math.atan2(event.getY() - h2, event.getX() - w2) / Math.PI);
        invalidate();
        return true;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        float w2 = getWidth() / 2f;
        float h2 = getHeight() / 2f;
        mMatrix.reset();
        mMatrix.postTranslate(w2, h2);
        canvas.concat(mMatrix);
        mPaint.setColor(0xaaff0000);
        canvas.drawPath(mCircle, mPaint);

        mMatrix.reset();
        mMatrix.postTranslate(60, 0);
        mMatrix.postRotate(mAngle);
        canvas.concat(mMatrix);
        mPaint.setColor(0xaa00ff00);
        canvas.drawPath(mTriangle, mPaint);
    }
}
于 2013-12-12T10:03:41.933 回答
0

由于我不知道您使用的是 open GL 还是标准 canevas,所以我无法真正给您一些工作代码。但总体思路是(假设您存储了三角形 (x, y) 的当前位置,并存储了圆心 (cx, cy)。

请执行下列操作:

v = (cx-x, cy-y) // v is the normal vector of your triangle: it faces the center of the circle
triangle.translate(v) // translate to the center of the circle
triangle.rotate(angle) // rotate the triangle on itself
v.rotate(angle) // apply the same rotation on the normal vector
triangle.translate(-v) // translate back on the circle, but since v is rotated, the position will be updated

我希望它足够清楚,祝你好运

编辑: 首先,您真的应该尝试更准确:在您的第一篇文章中,您没有说三角形是图像(这很重要)。然后你不说你当前的渲染是什么,什么有效,什么无效。我会更容易帮助您了解您的程序当前显示的内容。

从您的代码中,我假设您正确放置了三角形图像,但它没有旋转。所以首先,尝试添加

    //place the arrow indicating current temperature
    int curTempLeft = containerRight - ((containerWidth/2) + currTempWidth/2);
    int curTempTop = containerTop - (currTempHeight/2);
    int curTempRight = curTempLeft + currTempWidth;
    int curTempBottom = curTempTop + currTempHeight;

    mCurTempArrow.setRotate(angle); // rotate the image. angle is in degrees

    mCurTempArrow.layout(curTempLeft, curTempTop, curTempRight, curTempBottom);

如果您不知道角度,则可能必须从三角形的先前位置计算它

于 2013-12-12T08:05:46.197 回答