【绘制】HTML5 Canvas自定义坐标变换。transform()和setTransform()的介绍和使用

介绍

我们之前实现了旋转(rotate)、缩放(scale)和平移(translate),但是如果要实现更加复杂的坐标变换如“错切”就没那么容易了。

 

所以,接下来介绍更加基础的方法,来实现自定义的坐标变换。不仅能够实现旋转、错切和平移,也能够实现错切等等坐标变换。

自定义坐标变换

我们使用两个用于坐标变换的方法。

CanvasRenderingContext2D对象之中用于坐标变换的方法
方法描述

transform(double a,double b,double c,double d,double e,double f)

按照这个6个参数所代表的矩阵对当前坐标系进行变换
setTransform(double a,double b,double c,double d,double e,double f)先将当前对变换矩阵重置为单位矩阵,然后再按照这6个参数所代表对矩阵对坐标系进行变换

这6个参数的含义不能够用一两句话来说出来,为了让你理解,我们先看一下另外平移、缩放、旋转的代数方程。

平移

平移前的旧坐标(x,y),平移后的新坐标(x',y')。

x'=x+dx

y'=y+dy

 新旧坐标系的横向距离差记为dx,其中x你可以理解为单位x,所以根据dx和dy的值就能在x轴和y轴方向平移坐标系。

缩放

缩放前的旧坐标(x,y),平移后的新坐标(x',y')。

x'=x*sx

y'=y*sy

缩放倍数记为sx,其中x你可以理解为单位x,所以根据sx和sy的值就能实现缩放的功能。

旋转

旋转操作的等式需要用到一些三角函数

x' = x*cos(angle)-y*sin(angle)

y' = y*cos(angle)+x*sin(angle)

旋转角度为angle,例如将(5,10)以(0,0)为中心旋转45度,那么将会使其落在(3.5,10.6)这个位置上。

六个参数的含义

前面说transform(a,b,c,d,e,f)和setTransform(a,b,c,d,e,f)都有6个参数,这6个参数将会在一组等式中用到,该等式可以涵盖我们已经讲过的所有用于平移、缩放以及旋转的那些方程。

用于坐标变换的通式

x'=ax+cy+e

y'=bx+dy+f

 

a水平缩放。

b水平倾斜。

c垂直倾斜。

d垂直缩放。

e水平移动。

f垂直移动。

平移、缩放、旋转的自定义实现 

如果a,d=1;b,c=0;那么通过e,f就能实现平移,这种情况下等式就变成了

x'=x+e

y'=y+f

如果将b,c,e,f=0;那么通过a,d就能实现缩放,这种情况下等式就变成了

x'=ax

y'=dy 

如果将a=cos(angle);b=sin(angle);c=-sin(angle);d=cos(angle);e,f=0;就能实现旋转,这种情况下等式就变成了

x'=cos(angle)*x-sin(angle)*y+0

y'=sin(angle)*x+cos(angle)*y+0 

错切 

错切的效果只需要c和b的值就能实现了。当这种情况时:transform(1,0,0,1,0,0);

原图

当修改b和c的值时,transform(1,0,0.75,1,0,0);

修改c为0.75

将6个参数带入等式可以化简得到

x'=x+0.75x

y'=y 

上述等式对画布中每个点的x坐标进行了错切操作,同时保持y坐标不变,于是就产生了水平方向错切效果。竖直方向同理。

setTransform()的使用

transform()可以在当前变换矩阵上叠加运用另外的变换效果;这点其实setTransform()也可以做到,不过不同的是,setTransform()是先重置为默认单位矩阵后,再添加变换效果,这就意味着它会将之前的变换矩阵彻底清除。如果不带参数,则重置之后就不再添加变换效果。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在 Android 上绘制定义 X 和 Y 数据的折线图,可以在上一个问题中的基础上进行修改。你需要将数据点的坐标计算方式修改为根据 X 和 Y 值计算,而不是仅仅根据 Y 值计算。 下面是一个示例代码,实现了一个可以接受自定义 X 和 Y 数据的折线图绘制: ```java public class LineChartView extends View { private List<Float> mXData = new ArrayList<>(); private List<Float> mYData = new ArrayList<>(); public LineChartView(Context context) { super(context); } public LineChartView(Context context, AttributeSet attrs) { super(context, attrs); } public LineChartView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } public void setData(List<Float> xData, List<Float> yData) { mXData = xData; mYData = yData; invalidate(); // 通知 View 进行重新绘制 } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); // 设置画笔颜色和样式 Paint paint = new Paint(); paint.setColor(Color.BLUE); paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(5); // 计算每个数据点的坐标 int width = getWidth(); int height = getHeight(); float xInterval = width / (mXData.size() - 1); float yInterval = height / Collections.max(mYData); Path path = new Path(); for (int i = 0; i < mXData.size(); i++) { float x = mXData.get(i) * xInterval; float y = height - mYData.get(i) * yInterval; if (i == 0) { path.moveTo(x, y); } else { path.lineTo(x, y); } } // 绘制折线图 canvas.drawPath(path, paint); } } ``` 在 Activity 中,你可以通过调用 setData() 方法来设置折线图的 X 和 Y 数据,并将自定义 View 组件添加到布局中: ```java List<Float> xData = new ArrayList<>(); xData.add(1f); xData.add(2f); xData.add(3f); xData.add(4f); xData.add(5f); List<Float> yData = new ArrayList<>(); yData.add(10f); yData.add(20f); yData.add(50f); yData.add(30f); yData.add(40f); LineChartView lineChartView = new LineChartView(this); lineChartView.setData(xData, yData); LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams( LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT); linearLayout.addView(lineChartView, layoutParams); ``` 上述代码会在 LinearLayout 中添加一个折线图,其中 X 数据为 [1, 2, 3, 4, 5],Y 数据为 [10, 20, 50, 30, 40]。你可以根据自己的需求来修改上述代码,实现更加复杂的折线图绘制

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值