如何自建网站做外贸做网站图片无法显示的原因
news/
2025/9/22 22:00:50/
文章来源:
如何自建网站做外贸,做网站图片无法显示的原因,可以做设计兼职的网站,网站关键字怎么修改说到贝塞尔曲线#xff0c;大家肯定都不陌生#xff0c;网上有很多关于介绍和理解贝塞尔曲线的优秀文章和动态图。以下两个是比较经典的动图了。二阶贝塞尔曲线#xff1a;三阶贝塞尔曲线#xff1a;由于在工作中经常要和贝塞尔曲线打交道#xff0c;所以简单说一下自己的…说到贝塞尔曲线大家肯定都不陌生网上有很多关于介绍和理解贝塞尔曲线的优秀文章和动态图。以下两个是比较经典的动图了。二阶贝塞尔曲线三阶贝塞尔曲线由于在工作中经常要和贝塞尔曲线打交道所以简单说一下自己的理解现在假设我们要在坐标系中绘制一条直线直线的方程很简单就是 yx 很容易得到下图现在我们限制一下 x 的取值范围为 0~1 的闭区间那么可以得出 y 的取值范围也是 0~1。而在 0~1 的区间范围内x 能取的数有多少个呢答案当然是无数个了。同理y 的取值个数也是有无数个。每一个 x 都有唯一的 y 与之对应一个 (x,y) 在坐标系上就是一个点。所以最终得到的 0~1 区间的线段实际上是由无数的点组成的。那么这条线段有多长呢长度是由 x 的取值范围来决定的若 x 的取值为 0~2那么线段就长了一倍。另外如果 x 的取值范围不是无数个而是以 0.05 的间距从 0 到 1 之间递增那么得到的就是一串点了。由于 点 是一个理想状态下的描述在数学上点是没有宽高、没有面积的。但是如果你在草稿纸上绘制一个点不管你用到是铅笔、毛笔、水笔还是画笔一个点总是要占面积的。毛笔画一个点的面积可能需要铅笔画几十个点了。在实际生活中如果要以 0.05 的间距在第一幅坐标系图中画出 x 在 0~1 区间的一串点最终结果就和直接画一条线段没啥差别了。这就是现实和理想的差别了。理想一串点现实一条线。我们把这个逻辑放到手机屏幕上。手机屏幕上的最小显示单位就是像素了一个 1920 * 1080 的屏幕指的就是各方向上像素点的数量。假如绘制一条和屏幕一样宽的线段一个点最小就算一个像素最多也就 1080 个点了。点占的像素越多那么实际绘制时需要的点的数量越少这也算是潜在的优化项了。说完直线再回到贝塞尔曲线上。曲线和直线都有一个共同点它们都有各自特定的方程只不过我们用的直线例子比较简单既 y x 一眼看出计算结果。直线方程 y x在数学上可以这么描述y 是关于 x 的函数既 y F(x) 其中 x 的取值决定了该直线的长度。根据上面的理解这个长度的直线实际又是由在 x 的取值范围内对应的无数个点组成的。反观贝塞尔曲线方程以及对应的图形如下二阶贝塞尔曲线其中P0 和 P2 是起始点P1 是控制点。三阶贝塞尔曲线其中P0 和 P3 是起始点P1 和 P2 是控制点。不难理解假设我们要绘制一条曲线肯定要有起始和结束点来指定曲线的范围曲线。而控制点就是指定该曲线的弧度或者说指定该曲线的弯曲走向不同的控制点得出的曲线绘制结果是不一样的。另外可以观察到无论是几阶贝塞尔曲线都会有参数 t 以及 t 的取值范围限定。t 在 0~1 范围的闭区间内那么 t 的取值个数实际上就有无数个了这时的 t 就可以理解成上面介绍直线中讲到的 x 。这样一来就可以把起始点、控制点当初固定参数那么贝塞尔曲线计算公式就成了 B F(t) B 是关于 t 的函数而 t 的取值范围为 0~1 的闭区间。也就是说贝塞尔曲线选定了起始点和控制点照样可以看成是 t 在 0~1 闭区间内对应的无数个点所组成的。有了上面的阐述在工(ban)程(zhuan)的角度上就不难理解贝塞尔曲线到底怎么使用了。Android 绘制贝塞尔曲线Android 自带贝塞尔曲线绘制 API 通过 Path 类的 quadTo 和 cubicTo 方法就可以完成绘制。 1 // 构建 path 路径也就是选取 2 path.reset(); 3 path.moveTo(p0x, p0y); 4 // 绘制二阶贝塞尔曲线 5 path.quadTo(p1x, p1y, p2x, p2y); 6 path.moveTo(p0x, p0y); 7 path.close(); 8 9 // 最后的绘制操作10 canvas.drawPath(path, paint);这里的绘制实际上就是把贝塞尔曲线计算的方程式交给了 Android 系统内部去完成了参数传递上只传递了起始点和控制点。我们可以通过自己的代码来计算这个方程式从而对逻辑上获得更多控制权也就是把曲线拆分成许多个点组成如果点的尺寸比较大甚至可以减少点的个数实现同样的效果达到绘制优化的目的。OpenGL 绘制通过 OpenGL 可以实现我们上述的方案把曲线拆分成多个点组成。这种方案要求我们在 CPU 上去计算贝塞尔曲线方程根据 t 的每一个取值计算出一个贝塞尔点用 OpenGL 去绘制上这个点。这个点的绘制可以采用 OpenGL 中画三角形 GL_TRIANGLES 的形式去绘制这样就可以给点带上纹理效果不过这里面的坑略多起始点和控制点都是运行时动态可变的实现难度会大于固定不变的。这里先介绍另一种方案这种方案实现比较简单也能达到优化效果我们可以把贝塞尔曲线的计算方程式交给 GPU 在 OpenGL Shader 中去完成。这样一来我们只要给定起始点和控制点中间计算贝塞尔曲线去填补点的过程就交给 Shader 去完成了。另外通过控制 t 的数量我们可以控制贝塞尔点填补的疏密。t 越大填补的点越多超过一定阈值后不会对绘制效果有提升反而影响性能。t 越小那么贝塞尔曲线就退化成一串点组成了。所以说 t 的取值范围也能对绘制起到优化作用。绘制效果如下图所示以下就是实际的代码部分了关于 OpenGL 的基础理论部分可以参考之前写过的文章和公众号就不再阐述了。在 Shader 中定义一个函数实现贝塞尔方程1vec2 fun(in vec2 p0, in vec2 p1, in vec2 p2, in vec2 p3, in float t){2 float tt (1.0 - t) * (1.0 -t);3 return tt * (1.0 -t) *p0 4 3.0 * t * tt * p1 5 3.0 * t *t *(1.0 -t) *p2 6 t *t *t *p3;7}该方程可以利用 Shader 中自带的函数优化一波1vec2 fun2(in vec2 p0, in vec2 p1, in vec2 p2, in vec2 p3, in float t)2{3 vec2 q0 mix(p0, p1, t);4 vec2 q1 mix(p1, p2, t);5 vec2 q2 mix(p2, p3, t);6 vec2 r0 mix(q0, q1, t);7 vec2 r1 mix(q1, q2, t);8 return mix(r0, r1, t);9}接下来就是具体的顶点着色器 shader 1// 对应 t 数据的传递 2attribute float aData; 3// 对应起始点和结束点 4uniform vec4 uStartEndData; 5// 对应控制点 6uniform vec4 uControlData; 7// mvp 矩阵 8uniform mat4 u_MVPMatrix; 910void main() {11 vec4 pos;12 pos.w 1.0;13 // 取出起始点、结束点、控制点14 vec2 p0 uStartEndData.xy;15 vec2 p3 uStartEndData.zw;16 vec2 p1 uControlData.xy;17 vec2 p2 uControlData.zw;18 // 取出 t 的值19 float t aData;20 // 计算贝塞尔点的函数调用21 vec2 point fun2(p0, p1, p2, p3, t);22 // 定义点的 x,y 坐标23 pos.xy point;24 // 要绘制的位置25 gl_Position u_MVPMatrix * pos;26 // 定义点的尺寸大小27 gl_PointSize 20.0;28}代码中的 uStartEndData 对应起始点和结束点uControlData 对应两个控制点。这两个变量的数据传递通过 glUniform4f 方法就好了 1 mStartEndHandle glGetUniformLocation(mProgram, uStartEndData); 2 mControlHandle glGetUniformLocation(mProgram, uControlData); 3 // 传递数据作为固定值 4 glUniform4f(mStartEndHandle, 5 mStartEndPoints[0], 6 mStartEndPoints[1], 7 mStartEndPoints[2], 8 mStartEndPoints[3]); 9 glUniform4f(mControlHandle,10 mControlPoints[0],11 mControlPoints[1],12 mControlPoints[2],13 mControlPoints[3]); 另外重要的变量就是 aData 了它对应的就是 t 在 0~1 闭区间的划分的数量。1 private float[] genTData() {2 float[] tData new float[Const.NUM_POINTS];3 for (int i 0; i tData.length; i ) {4 float t (float) i / (float) tData.length;5 tData[i] t;6 }7 return tData;8 }以上函数就是把 t 在 0~1 闭区间分成 Const.NUM_POINTS 份每一份的值都存在 tData 数组中最后通过 glVertexAttribPointer 函数传递给 Shader 。最后实际绘制时我们采用 GL_POINTS 的形式绘制就好了。1 GLES20.glDrawArrays(GLES20.GL_POINTS, 0, Const.NUM_POINTS );以上就是 OpenGL 绘制贝塞尔曲线的小实践。具体的代码部分可以参考我的项目https://github.com/glumes/AndroidOpenGLTutorial在参考中也有一个 OpenGL 绘制贝塞尔曲线的例子不过他绘制的是贝塞尔曲线面采用的是 GL_TRIANGLES 的形式而且在 tData 数组的构造也有些不同但是都大同小异了看明白了本文的例子也不难理解参考的文章。关于 OpenGL 相关的文章可以参考我之前写过的公众号内容OpenGL 系列---基础绘制流程OpenGL 学习系列---基本形状的绘制OpenGL 学习系列---坐标系统OpenGL 学习系列---投影矩阵OpenGL 学习系列 --- 纹理OpenGL 学习系列---观察矩阵OpenGL ES 学习资源分享用 OpenGL 对视频帧内容进行替换参考https://yalantis.com/blog/how-we-created-visualization-for-horizon-our-open-source-library-for-sound-visualization/
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/910518.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!