Android,如何围绕固定点旋转箭头(图像)?

发布于 2024-12-04 15:07:28 字数 212 浏览 0 评论 0原文

我有一个箭头图像,我想从 0 度旋转到 180 度(就像一米中的针一样)。箭头的一个点固定在屏幕的中间和底部,箭头头应该移动。箭头的长度是固定的(它是图像)。我还有两个按钮,我希望箭头在触摸左侧按钮时向左转,在触摸右侧按钮时向右转。

这个过程的逻辑是什么?

在此处输入图像描述

I have an arrow image that I want to rotate from 0 to 180 degree (like the needle in a meter.) One point of the arrow is fixed in middle and at bottom of the screen and head of arrow should move. Length of arrow is fix (it is image). Also I have two buttons and I want arrow to turn left when button left is touched and turn right when right button is touched.

What is the logic of this process?

enter image description here

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

睫毛上残留的泪 2024-12-11 15:07:28

如果您使用画布进行绘图(就像您的情况一样),这实际上非常简单。

鉴于您知道图像应围绕其旋转的点的坐标,您可以这样做:

private void doDraw(Canvas canvas) {
canvas.save();
float px = ...;
float py = ...;
canvas.rotate(degrees, px, py);
arrow.draw(canvas);
canvas.restore();
}

度数将是一个整数值,当用户单击 L 或 R 按钮时,该值会递增/递减。 canvas.rotate 会处理剩下的事情!

This is actually pretty simple if you are using a canvas to do your drawing(as you should in your case).

Given that you know the coordinates for the point around which the image should rotate, you can do it like this:

private void doDraw(Canvas canvas) {
canvas.save();
float px = ...;
float py = ...;
canvas.rotate(degrees, px, py);
arrow.draw(canvas);
canvas.restore();
}

degrees will be a integer value that you increment/decrement when the user clicks the L or R buttons. canvas.rotate takes care of the rest!

对风讲故事 2024-12-11 15:07:28

你必须在android中使用3d旋转来处理可能的动画,并尝试使用矩阵旋转......我有这方面的位图代码......

Bitmap bmp=BitmapFactory.decodeResource(getResources(), R.drawable.bar);
                Matrix mtx = new Matrix();
  mtx.postRotate(180);   // rotating 180 degrees clockwise
  Bitmap rotatedBMP = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth() ,bmp.getHeight() , mtx, true);  // creating the bitmap image with new angle

也检查这个

http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/animation/Rotate3dAnimation.html

You have to work with probably animation using 3d rotation in android and try to also usong Matrix Rotation ...I have bitmap code for this.........

Bitmap bmp=BitmapFactory.decodeResource(getResources(), R.drawable.bar);
                Matrix mtx = new Matrix();
  mtx.postRotate(180);   // rotating 180 degrees clockwise
  Bitmap rotatedBMP = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth() ,bmp.getHeight() , mtx, true);  // creating the bitmap image with new angle

also check this

http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/animation/Rotate3dAnimation.html

山有枢 2024-12-11 15:07:28

所以有简短的答案和长的答案。

简而言之,位图和画布的旋转是一个常见功能,通常称为“旋转”,并且通常以旋转点为中心。

更长的答案是,所有 2D 和 3D 图形都会转化为矩阵代数的技巧。对于每个点:
新_x = 因子_1 * 旧_x + 因子_2 * 旧_y + 因子_3
...

这些因素在矩阵中发挥得非常好,这就是矩阵如此受欢迎的原因。有一个很酷的技巧,可以将变换链接在一起,因此您可以将问题表述为“拿起旧画布,移动它,使触摸点成为原点,旋转它,然后移动它,使原点回到原点”触摸的点。”或者 Matrix m = new Matrix().postTranslate(-touch_x, -touch_y).postRotate(360/20).postTranslate(touch_x, touch_y) 每次将其旋转 1/20 圆。然后将矩阵传递给任何采用“变换”矩阵的函数。

最酷的是,您只需对该矩阵执行一次所有计算,然后对每个点使用相同的 4 次乘法和一堆加法。事实上,这种情况非常常见,视频卡和英特尔指令集都在硬件中执行此操作。您也可以将结果图像再次乘以相同的矩阵以获得下一个图像。

现在,如果您真的要求图形黑客如何在没有内存的情况下在一些非常快的汇编代码中执行此操作,那么技巧就是将旋转和错误挑选到不需要缓冲区的小链中。例如,一个简单的 90 度旋转首先会交换四个角,然后交换(左上 + 1 左进入右上 + 1 下进入右下 - 1 左进入左下 - 1 下,这返回左上角 + 1)。这些技巧通常只对内存限制有用。

信息太多了。告诉我们更多有关您的问题的信息。

So there is the short answer and the long answer.

The short answer is that rotation of bitmaps and canvasses is a common function, usually called "rotate" and usually taking the point around which to rotate.

The longer answer is that all 2D and 3D graphics devolve into a trick of matrix algebra. For each point:
new_x = factor_1 * old_x + factor_2 * old_y + factor_3
...

These factors work really nicely in a matrix, and is why the matrix thing got so popular. There is a cool trick where you chain the transformations together, so you might state your problems as "take the old canvas, move it so that the touched point is the origin, rotate it, and then move it so that the origin is back at the touched point." Or Matrix m = new Matrix().postTranslate(-touch_x, -touch_y).postRotate(360/20).postTranslate(touch_x, touch_y) to rotate it by 1/20th of circle each time. Then you pass the matrix to any function that takes the "transformation" matrix.

The cool thing is that you do all the calculations for that matrix just once, and then use the same 4 multiplications on each point and a bunch of adding. In fact, this is so common that video cards and the Intel instruction set both do this stuff in hardware. You can also just multiply the resulting image again by the same matrix to get the next one.

Now, if you are really asking for the graphics hack of how do I do this in some insanely fast assembly code with no memory, the trick is to pick rotations and errors into little chains where you don't need a buffer. For example, a simple 90 degree rotation would first swap the four corners, then it would swap (upper left + 1 left goes into upper right + 1 down which goes into lower right - 1 left which goes into lower left - 1 down, which goes back into the upper left + 1). These tricks usually only matter for memory constraints.

Way too much information. Tell us more about your problem.

蛮可爱 2024-12-11 15:07:28
ImageView arrow = findViewById(/* id of your arrow */);
int width = arrow.getWidth();
int height = arrow.getHeight();
newAngle = /* init it by needed angle */;
RotateAnimation animation = new RotateAnimation(oldAngle, newAngle, width / 2, height);
oldAngle = newAngle;
animation.setDuration(200); // you may  set another duration
animation.setFillAfter(true);
arrow.startAnimation(animation);

祝你好运!

ImageView arrow = findViewById(/* id of your arrow */);
int width = arrow.getWidth();
int height = arrow.getHeight();
newAngle = /* init it by needed angle */;
RotateAnimation animation = new RotateAnimation(oldAngle, newAngle, width / 2, height);
oldAngle = newAngle;
animation.setDuration(200); // you may  set another duration
animation.setFillAfter(true);
arrow.startAnimation(animation);

Good luck!

夜吻♂芭芘 2024-12-11 15:07:28

我看到这个示例和我或多或少适应了您需要的工作,请参阅示例以更好地理解我的代码:)


import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.os.Bundle;
import android.widget.ImageView;
import android.widget.SeekBar;

public class TesteRotateActivity extends Activity implements
    SeekBar.OnSeekBarChangeListener {

private ImageView myImageView;
private SeekBar seekbarRotate;
private float curScale = 1F;
private float curRotate = 0F;
private Bitmap bitmap;
private int bmpHeight;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    myImageView = (ImageView) findViewById(R.id.imageview);
    seekbarRotate = (SeekBar) findViewById(R.id.rotate);
    bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.teste);//here you insert your image
    bmpHeight = bitmap.getHeight();
    drawMatrix();
    seekbarRotate.setOnSeekBarChangeListener(this);
}

private void drawMatrix() {
    Matrix matrix = new Matrix();
    Matrix matrixb = new Matrix();
    Matrix matrixc = new Matrix();
    matrix.postScale(curScale, curScale);
    matrixb.setRotate(curRotate, 100, bmpHeight);
    matrixc.setTranslate(100, 0);
    matrix.setConcat(matrixb, matrixc);
    Bitmap targetBitmap = Bitmap.createBitmap(200, bmpHeight,
            bitmap.getConfig());
    Canvas canvas = new Canvas(targetBitmap);
    canvas.drawBitmap(bitmap, matrix, new Paint());
    myImageView.setImageBitmap(targetBitmap);
}

@Override
public void onProgressChanged(SeekBar seekBar, int progress,
        boolean fromUser) {
    curRotate = (float) progress;
    drawMatrix();
}

@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}

@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}

}

main 的 xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >

<TextView
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="@string/app_name" />

<SeekBar
    android:id="@+id/rotate"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_margin="5px"
    android:max="360"
    android:progress="0" />

<ImageView
    android:id="@+id/imageview"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:scaleType="center" />

</LinearLayout>

i see this example and i adapted to work more or less like you need, please see the example for a better understanding of my code :)


import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.os.Bundle;
import android.widget.ImageView;
import android.widget.SeekBar;

public class TesteRotateActivity extends Activity implements
    SeekBar.OnSeekBarChangeListener {

private ImageView myImageView;
private SeekBar seekbarRotate;
private float curScale = 1F;
private float curRotate = 0F;
private Bitmap bitmap;
private int bmpHeight;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    myImageView = (ImageView) findViewById(R.id.imageview);
    seekbarRotate = (SeekBar) findViewById(R.id.rotate);
    bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.teste);//here you insert your image
    bmpHeight = bitmap.getHeight();
    drawMatrix();
    seekbarRotate.setOnSeekBarChangeListener(this);
}

private void drawMatrix() {
    Matrix matrix = new Matrix();
    Matrix matrixb = new Matrix();
    Matrix matrixc = new Matrix();
    matrix.postScale(curScale, curScale);
    matrixb.setRotate(curRotate, 100, bmpHeight);
    matrixc.setTranslate(100, 0);
    matrix.setConcat(matrixb, matrixc);
    Bitmap targetBitmap = Bitmap.createBitmap(200, bmpHeight,
            bitmap.getConfig());
    Canvas canvas = new Canvas(targetBitmap);
    canvas.drawBitmap(bitmap, matrix, new Paint());
    myImageView.setImageBitmap(targetBitmap);
}

@Override
public void onProgressChanged(SeekBar seekBar, int progress,
        boolean fromUser) {
    curRotate = (float) progress;
    drawMatrix();
}

@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}

@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}

}

the xml of main

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >

<TextView
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="@string/app_name" />

<SeekBar
    android:id="@+id/rotate"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_margin="5px"
    android:max="360"
    android:progress="0" />

<ImageView
    android:id="@+id/imageview"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:scaleType="center" />

</LinearLayout>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文