当前位置:首页 » 安卓系统 » matrixandroid旋转

matrixandroid旋转

发布时间: 2022-10-18 04:41:23

Ⅰ Android中的Matrix,以及set,pre和post的区别

Matrix包含一个3 X 3的矩阵,专门用于图像变换匹配。

Matrix提供了四种操作:
translate(平移)
rotate(旋转)
scale(缩放)
skew(倾斜)
也就是说这4种操作都是对这个3 X 3的矩阵设值来达到变换的效果。
Matrix没有结构体,它必须被初始化,通过reset或set方法。
OK,Matrix介绍完了,我们来看看set、pre、post的区别。
pre是在队列最前面插入,post是在队列最后面追加,而set先清空队列在添加(这也是上文提到的“Matrix没有结构体,它必须被初始化,通过reset或set方法”的原因)。
下面通过一些例子具体说明:
matrix.preScale(2f,1f);
matrix.preTranslate(5f, 0f);
matrix.postScale(0.2f, 1f);
matrix.postTranslate(0.5f, 0f);
执行顺序:translate(5, 0) -> scale(2f, 1f) -> scale(0.2f, 1f) -> translate(0.5f, 0f)
matrix.postTranslate(2f, 0f);
matrix.preScale(0.2f, 1f);
matrix.setScale(1f, 1f);
matrix.postScale(5f, 1f);
matrix.preTranslate(0.5f, 0f);

执行顺序:translate(0.5f, 0f) -> scale(1f, 1f) -> scale(5f, 1)

Ⅱ android 怎么让图片实现朝Z轴的方向旋转RotateAnimation是x y方向的,我想要包含z方向的

RotateAnimation是不可以绕Z轴旋转的,如果LZ想要实现Z轴旋转效果,可以看下matrix这个类(实际还是opengl),可以给LZ例举下:
rotateX(float degree) 绕着x轴旋转degree个度数
rotateY(float degree) 绕着y轴旋转degree个度数
rotateZ(float degree) 绕着z轴旋转degree个度数

Ⅲ android Matrix.setRotate 和 postRotate的区别

Matrix主要用于对平面进行平移(Translate),缩放(Scale),旋转(Rotate)以及斜切(Skew)操作。
为简化矩阵变换,Android封装了一系列方法来进行矩阵变换;其中包括:
set系列方法:setTranslate,setScale,setRotate,setSkew;设置,会覆盖之前的参数。
pre系列方法:preTranslate,preScale,preRotate,preSkew;矩阵先乘,如M' = M * T(dx, dy)。
post系列方法:postTranslate,postScale,postRotate,postSkew;矩阵后乘,如M' = T(dx, dy) * M。
通过将变换矩阵与原始矩阵相乘来达到变换的目的,例如:
平移(x'=x+tx;y'=y+ty):

缩放(x'=sx*x;y'=sy*y):

旋转(x'=cosβ*x-sinβ*y;y'=sinβ*x+cosβ*y):

选择需要用到如下的三角函数的公式:
①sin(α+β)=sinαcosβ+cosαsinβ
②cos(α+β)=cosαcosβ-sinαsinβ
公式①可以由单位圆方法或托勒密定理推导出来。
推导过程参见:http://blog.sina.com.cn/s/blog_58260f420100c03j.html
斜切(x'=x+k1*y;y'=k2*x+y):

//源码文件:external\skia\legacy\src\core\SkMatrix.cpp

#define SK_Scalar1 (1.0f)
#define kMatrix22Elem SK_Scalar1
typedef float SkScalar;
#define SkScalarMul(a, b) ((float)(a) * (b))

enum {
kMScaleX, kMSkewX, kMTransX,
kMSkewY, kMScaleY, kMTransY,
kMPersp0, kMPersp1, kMPersp2
};

void SkMatrix::reset() {
fMat[kMScaleX] = fMat[kMScaleY] = SK_Scalar1; //其值为1
fMat[kMSkewX] = fMat[kMSkewY] =
fMat[kMTransX] = fMat[kMTransY] =
fMat[kMPersp0] = fMat[kMPersp1] = 0; //其值,全为0
fMat[kMPersp2] = kMatrix22Elem; //其值为1
this->setTypeMask(kIdentity_Mask | kRectStaysRect_Mask);
}

void SkMatrix::setTranslate(SkScalar dx, SkScalar dy) {
if (SkScalarToCompareType(dx) || SkScalarToCompareType(dy)) {
fMat[kMTransX] = dx; //以新值dx覆盖原值,原值无效了
fMat[kMTransY] = dy;

fMat[kMScaleX] = fMat[kMScaleY] = SK_Scalar1; //其值为1
fMat[kMSkewX] = fMat[kMSkewY] =
fMat[kMPersp0] = fMat[kMPersp1] = 0; //其值,全为0
fMat[kMPersp2] = kMatrix22Elem; //其值为1

this->setTypeMask(kTranslate_Mask | kRectStaysRect_Mask);
} else {
this->reset();
}
}

bool SkMatrix::preTranslate(SkScalar dx, SkScalar dy) {
if (this->hasPerspective()) {
SkMatrix m;
m.setTranslate(dx, dy);
return this->preConcat(m); //矩阵的先乘运算
}

if (SkScalarToCompareType(dx) || SkScalarToCompareType(dy)) {
fMat[kMTransX] += SkScalarMul(fMat[kMScaleX], dx) +
SkScalarMul(fMat[kMSkewX], dy); //先乘,需要矩阵运算过
fMat[kMTransY] += SkScalarMul(fMat[kMSkewY], dx) +
SkScalarMul(fMat[kMScaleY], dy);

this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask);
}
return true;
}

bool SkMatrix::postTranslate(SkScalar dx, SkScalar dy) {
if (this->hasPerspective()) {
SkMatrix m;
m.setTranslate(dx, dy);
return this->postConcat(m); //矩阵的后乘运算
}

if (SkScalarToCompareType(dx) || SkScalarToCompareType(dy)) {
fMat[kMTransX] += dx; //后乘,直接加新值dx即可
fMat[kMTransY] += dy;
this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask);
}
return true;
}

bool SkMatrix::preConcat(

Ⅳ android,怎么让imageview旋转的很自然,我使用了Matrix类,然后通过Handler中的postDelayted方法

使用动画,你网络一下,有很多例子的。

Ⅳ android Matrix.setRotate 和 postRotate的区别

其实Matrix方法中的setRotate()方法会先清除该矩阵,即设为单位矩阵。之后设置旋转操作的,同样,setTranslate()等方法也是一样的。所以是不能叠加各种效果在一起的,因此会出现我上述的问题。

所以,如果是想多种效果同时使用的话,用postRotate(), postTranslate()等类似的矩阵变换方法吧。

Ⅵ 求助,怎么用android实现控件的3D立体旋转效果

  • 实现水平滑动,所以可在手势抬起的时候进行判断并处理,是滑动显得流畅,代码如下:

java">packagecom.example.rotation3dview;
importandroid.content.Context;
importandroid.graphics.Camera;
importandroid.graphics.Canvas;
importandroid.graphics.Matrix;
importandroid.util.AttributeSet;
importandroid.view.MotionEvent;
importandroid.view.VelocityTracker;
importandroid.view.View;
importandroid.view.ViewDebug.HierarchyTraceType;
importandroid.view.ViewGroup;
importandroid.widget.ImageView;
importandroid.widget.Scroller;

{
privateintmCurScreen=1;
//滑动的速度
privatestaticfinalintSNAP_VELOCITY=500;
;
privateintmWidth;
privateScrollermScroller;
privateCameramCamera;
privateMatrixmMatrix;
//旋转的角度,可以进行修改来观察效果
privatefloatangle=90;
publicRote3DView(Contextcontext,AttributeSetattrs){
super(context,attrs);
mScroller=newScroller(context);
mCamera=newCamera();
mMatrix=newMatrix();
initScreens();
}

publicvoidinitScreens(){
ViewGroup.LayoutParamsp=newViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT);
for(inti=0;i<3;i++){
this.addView(newImageView(this.getContext()),i,p);
}
((ImageView)this.getChildAt(0)).setImageResource(R.drawable.page1);
((ImageView)this.getChildAt(1)).setImageResource(R.drawable.page2);
((ImageView)this.getChildAt(2)).setImageResource(R.drawable.page3);
}

@Override
protectedvoidonLayout(booleanchanged,intl,intt,intr,intb){
intchildLeft=0;
finalintchildCount=getChildCount();
for(inti=0;i<childCount;i++){
finalViewchildView=getChildAt(i);
if(childView.getVisibility()!=View.GONE){
finalintchildWidth=childView.getMeasuredWidth();
childView.layout(childLeft,0,childLeft+childWidth,childView.getMeasuredHeight());
childLeft+=childWidth;
}
}
}

@Override
protectedvoidonMeasure(intwidthMeasureSpec,intheightMeasureSpec){
super.onMeasure(widthMeasureSpec,heightMeasureSpec);
finalintwidth=MeasureSpec.getSize(widthMeasureSpec);
finalintwidthMode=MeasureSpec.getMode(widthMeasureSpec);
if(widthMode!=MeasureSpec.EXACTLY){
thrownewIllegalStateException("仅支持精确尺寸");
}
finalintheightMode=MeasureSpec.getMode(heightMeasureSpec);
if(heightMode!=MeasureSpec.EXACTLY){
thrownewIllegalStateException("仅支持精确尺寸");
}
finalintcount=getChildCount();
for(inti=0;i<count;i++){
getChildAt(i).measure(widthMeasureSpec,heightMeasureSpec);
}
scrollTo(mCurScreen*width,0);
}

privatefloatmDownX;
@Override
publicbooleanonTouchEvent(MotionEventevent){
if(mVelocityTracker==null){
mVelocityTracker=VelocityTracker.obtain();
}
//将当前的触摸事件传递给VelocityTracker对象
mVelocityTracker.addMovement(event);
floatx=event.getX();
switch(event.getAction()){
caseMotionEvent.ACTION_DOWN:
if(!mScroller.isFinished()){
mScroller.abortAnimation();
}
mDownX=x;
break;
caseMotionEvent.ACTION_MOVE:
intdisX=(int)(mDownX-x);
mDownX=x;
scrollBy(disX,0);
break;
caseMotionEvent.ACTION_UP:
=mVelocityTracker;
velocityTracker.computeCurrentVelocity(1000);
intvelocityX=(int)velocityTracker.getXVelocity();
if(velocityX>SNAP_VELOCITY&&mCurScreen>0){
snapToScreen(mCurScreen-1);
}elseif(velocityX<-SNAP_VELOCITY&&mCurScreen<getChildCount()-1){
snapToScreen(mCurScreen+1);
}else{
snapToDestination();
}
if(mVelocityTracker!=null){
mVelocityTracker.recycle();
mVelocityTracker=null;
}
break;
}
returntrue;
}

@Override
publicvoidcomputeScroll(){
if(mScroller.computeScrollOffset()){
scrollTo(mScroller.getCurrX(),mScroller.getCurrY());
postInvalidate();
}
}

publicvoidsnapToDestination(){
setMWidth();
finalintdestScreen=(getScrollX()+mWidth/2)/mWidth;
snapToScreen(destScreen);
}

publicvoidsnapToScreen(intwhichScreen){
whichScreen=Math.max(0,Math.min(whichScreen,getChildCount()-1));
setMWidth();
intscrollX=getScrollX();
intstartWidth=whichScreen*mWidth;
if(scrollX!=startWidth){
intdelta=0;
intstartX=0;
if(whichScreen>mCurScreen){
setPre();
delta=startWidth-scrollX;
startX=mWidth-startWidth+scrollX;
}elseif(whichScreen<mCurScreen){
setNext();
delta=-scrollX;
startX=scrollX+mWidth;
}else{
startX=scrollX;
delta=startWidth-scrollX;
}
mScroller.startScroll(startX,0,delta,0,Math.abs(delta)*2);
invalidate();
}
}

privatevoidsetNext(){
intcount=this.getChildCount();
Viewview=getChildAt(count-1);
removeViewAt(count-1);
addView(view,0);
}

privatevoidsetPre(){
intcount=this.getChildCount();
Viewview=getChildAt(0);
removeViewAt(0);
addView(view,count-1);
}

privatevoidsetMWidth(){
if(mWidth==0){
mWidth=getWidth();
}
}
}
  • 实现立体效果,添加如下代码:

/*
*当进行View滑动时,会导致当前的View无效,该函数的作用是对View进行重新绘制调用drawScreen函数
*/
@Override
protectedvoiddispatchDraw(Canvascanvas){
finallongdrawingTime=getDrawingTime();
finalintcount=getChildCount();
for(inti=0;i<count;i++){
drawScreen(canvas,i,drawingTime);
}
}

publicvoiddrawScreen(Canvascanvas,intscreen,longdrawingTime){
//得到当前子View的宽度
finalintwidth=getWidth();
finalintscrollWidth=screen*width;
finalintscrollX=this.getScrollX();
//偏移量不足的时
if(scrollWidth>scrollX+width||scrollWidth+width<scrollX){
return;
}
finalViewchild=getChildAt(screen);
finalintfaceIndex=screen;
finalfloatcurrentDegree=getScrollX()*(angle/getMeasuredWidth());
finalfloatfaceDegree=currentDegree-faceIndex*angle;
if(faceDegree>90||faceDegree<-90){
return;
}
finalfloatcenterX=(scrollWidth<scrollX)?scrollWidth+width
:scrollWidth;
finalfloatcenterY=getHeight()/2;
finalCameracamera=mCamera;
finalMatrixmatrix=mMatrix;
canvas.save();
camera.save();
camera.rotateY(-faceDegree);
camera.getMatrix(matrix);
camera.restore();
matrix.preTranslate(-centerX,-centerY);
matrix.postTranslate(centerX,centerY);
canvas.concat(matrix);
drawChild(canvas,child,drawingTime);
canvas.restore();
}

    Ⅶ android 中用画布旋转图片的时候怎么让让他 围着一个坐标旋转

    方法只有一种。

    步骤:

    1、画布平移坐标原点

    2、旋转画布

    示例代码

    canvas.save();//保存当前画布状态
    canvas.translate(x,y);//将坐标中心平移到要围绕的坐标点x,y
    canvas.rotate(90);//旋转角度,这里比如90度
    canvas.restore();//恢复画图状态到保存前

    Ⅷ android如何利用matrix类直接对图元进行旋转、平移等操作而不是对Bitmap进行操作。

    如果图元放在ImageView里,可以用这个方式来设置
    ImageView.setScaleType(ScaleType.MATRIX);
    matrix.postTranslate(x,y);//平移方法
    matrix.postScale(scalex,scaleY,midPointX,midPointY);//缩放
    ImageView.setImageMatrix(matrix);

    Ⅸ android怎么实现图片旋转

    可以使用RotateAnimation动画实现,设定无限循环即可

    代码如下

    {

    ImageViewiv;
    @Override
    protectedvoidonCreate(BundlesavedInstanceState){
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_two);
    iv=(ImageView)findViewById(R.id.image);
    RotateAnimationanimation=newRotateAnimation(0,360);
    animation.setDuration(100000);//设定转一圈的时间
    animation.setRepeatCount(Animation.INFINITE);//设定无限循环
    animation.setRepeatMode(Animation.RESTART);
    iv.startAnimation(animation);
    }
    }


    也可以自定义view继承于imageview,启动一个线程,在while循环里设置view的旋转角度


    {

    privatefloatmCurDegree=0;//当前旋转角度
    publicRotateView(Contextcontext,AttributeSetattrs){
    super(context,attrs);
    newThread(this).start();
    }

    @Override
    protectedvoidonLayout(booleanchanged,intleft,inttop,intright,
    intbottom){
    super.onLayout(changed,left,top,right,bottom);
    //设定旋转中心
    setPivotX(getMeasuredWidth()/2);
    setPivotY(getMeasuredHeight()/2);
    }

    @Override
    publicvoidrun(){
    while(true){
    setRotation(mCurDegree);
    mCurDegree+=5;
    postInvalidate();
    SystemClock.sleep(16);
    }
    }
    }

    在布局文件里使用RotateView代替imageview即可

    热点内容
    centos7编译安装php 发布:2025-03-10 18:32:48 浏览:492
    电脑上什么安卓模拟器 发布:2025-03-10 18:32:47 浏览:20
    公司ftp传输文件 发布:2025-03-10 18:24:54 浏览:384
    aspsql注入过滤 发布:2025-03-10 18:19:37 浏览:464
    编译表频率 发布:2025-03-10 18:02:59 浏览:776
    宝马330多哪些配置 发布:2025-03-10 18:01:33 浏览:765
    我的世界神奇宝贝最良心的服务器 发布:2025-03-10 18:01:29 浏览:238
    6有数据库 发布:2025-03-10 17:55:05 浏览:31
    如何看macbook配置参数 发布:2025-03-10 17:54:25 浏览:75
    电脑打开b站找不到服务器 发布:2025-03-10 17:44:04 浏览:135