标题: [原创代码] Perl绘制Bezier曲线渐变效果 [打印本页]
作者: 523066680 时间: 2015-3-19 10:41 标题: Perl绘制Bezier曲线渐变效果
环境:WinXP/Win7 Perl v5.16.3
需要图形渲染模块:OpenGL
单条Bezier的绘制函数参考 Wikipedia:貝茲曲線- =info
- Code By 523066680/vicyang
- 2015-01-02
- =cut
-
- use v5.16;
- use IO::Handle;
- use OpenGL qw/ :all /;
- use OpenGL::Config;
- use Time::HiRes 'sleep';
-
- STDOUT->autoflush(1);
-
- our $WinID;
- &Main();
-
- sub delta {
- my ($pta, $ptb) = @_;
- my $dtx = ($ptb->[0] - $pta->[0]);
- my $dty = ($ptb->[1] - $pta->[1]);
- my $delta = sqrt ($dtx ** 2 + $dty ** 2);
- return ($delta, $dtx, $dty);
- }
-
- sub PointOnCubicBezier {
- my ($cp0, $cp1, $cp2, $cp3, $t) = @_;
-
- my ($cx, $bx, $ax, $cy, $by, $ay);
- my ($tSquared, $tCubed, $result);
-
- $cx = 3.0 * ($cp1->[0] - $cp0->[0]);
- $bx = 3.0 * ($cp2->[0] - $cp1->[0]) - $cx;
- $ax = $cp3->[0] - $cp0->[0] - $cx - $bx;
-
- $cy = 3.0 * ($cp1->[1] - $cp0->[1]);
- $by = 3.0 * ($cp2->[1] - $cp1->[1]) - $cy;
- $ay = $cp3->[1] - $cp0->[1] - $cy - $by;
-
- $tSquared = $t **2;
- $tCubed = $t **3;
-
- $result->[0] = (
- ($ax * $tCubed) +
- ($bx * $tSquared) +
- ($cx * $t) +
- $cp0->[0]
- );
- $result->[1] = (
- ($ay * $tCubed) +
- ($by * $tSquared) +
- ($cy * $t) +
- $cp0->[1]
- );
-
- return $result;
- }
-
- sub getRevPoint {
- my ($A, $O, $B) = (shift, shift, undef);
-
- $B->[0] = $O->[0] + ($O->[0] - $A->[0]);
- $B->[1] = $O->[1] + ($O->[1] - $A->[1]);
-
- return $B;
- }
-
- sub display {
- state $count = 0;
- state $loops = 0;
-
- my ($i, $j);
- my $coord;
-
- my ($dt, $dtx, $dty);
-
- state $n_cpts = 4; #四个控制点
- state $cpts_path_parts = 50;
- state $bezier_parts = 30; #每条贝塞尔曲线分30部分
- state $n_bezier = 30; #贝塞尔曲线的堆叠数量
- state $curve = []; #每个cpt的曲线路径存储
- state $pti = 0; #pti数组记录4个cpt的其自身的cpt'坐标
- state $pt = [
- [0.0, 0.0],
- [0.0, 0.0],
- [0.0, 0.0],
- [0.0, 0.0],
- ];
-
- state $ptarr = [];
-
- if (($loops == 0) and ($count == 0)) {
- for $i (0 .. $n_bezier-1) {
- for $j (0 .. $bezier_parts) {
- $ptarr->[$i][$j] = [1000.0, -1000.0];
- }
-
- $curve->[$i] = [
- [rand(200)-100.0, rand(200)-100.0],
- [rand(200)-100.0, rand(200)-100.0],
- [rand(200)-100.0, rand(200)-100.0],
- [rand(200)-100.0, rand(200)-100.0]
- ]
- }
- }
-
- #处理四个控制点的演变
- RECOUNT:
- if ( $pti <= $cpts_path_parts ) {
- for $i (0 .. $n_cpts-1) {
- $coord = &PointOnCubicBezier(
- @{$curve->[$i]}[0..3],
- $pti/$cpts_path_parts
- );
- $pt->[$i] = $coord; #第 $i+1 个 cpt 的坐标
- }
- $pti++;
- } else {
- #控制点超过50次的时候,创建新的随机控制点,从头开始
- #起点是上一次的第50个点,同时也是新曲线的第0点
- #为了避免点重合,新的曲线点下标从1开始,而不是0开始
- for $i (0 .. $n_cpts-1) {
- $curve->[$i] = [
- $pt->[$i],
- getRevPoint($curve->[$i][2], $curve->[$i][3]),
- #Control Point 3 is A, Point 4 is O, Find Point B
- [rand(200)-100.0, rand(200)-100.0],
- [rand(200)-100.0, rand(200)-100.0]
- ];
- }
- $pti = 1;
- goto RECOUNT;
- }
-
-
- glClear(GL_COLOR_BUFFER_BIT);
- glBlendFunc(GL_SRC_ALPHA, GL_DST_ALPHA);
-
- glPushMatrix();
- for $i (0 .. $bezier_parts ) {
- $coord = &PointOnCubicBezier(
- @{$pt}[0, 1, 2, 3],
- $i/$bezier_parts
- );
- $ptarr->[$count][$i] = $coord;
- }
-
- glBegin(GL_POINTS);
-
-
- for $i (0 .. $n_bezier-1) {
- glColor4f(0.4, 0.6, 0.8, 0.5);
- for $j (0.0 .. $bezier_parts) {
- glVertex3f($ptarr->[$i][$j][0], $ptarr->[$i][$j][1], 0.0);
- }
- }
- glEnd();
-
- glPopMatrix();
- glutSwapBuffers();
-
- if ($count < ($n_bezier-1)) {
- $count++;
- } else {
- $count = 0;
- $loops++;
- }
-
- }
-
- sub init {
- glClearColor(0.0, 0.0, 0.0, 1.0);
- glPointSize(6.0);
- glLineWidth(10.0);
- glEnable(GL_BLEND);
- glEnable(GL_POINT_SMOOTH);
- glEnable(GL_LINE_SMOOTH);
- }
-
- sub idle {
- sleep 0.05;
- glutPostRedisplay();
- }
-
- sub Reshape {
- glViewport(0.0,0.0,500.0,500.0);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glOrtho(-100.0,100.0,-100.0,100.0,0.0,200.0);
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- gluLookAt(0.0,0.0,100.0,0.0,0.0,0.0, 0.0,1.0,100.0);
- }
-
- sub hitkey {
- my $key = shift;
- if (lc(chr($key)) eq 'q') {
- glutDestroyWindow($WinID);
- } elsif ($key == 27) {
- glutDestroyWindow($WinID);
- }
- }
-
- sub Main {
- glutInit();
- glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE );#| GLUT_MULTISAMPLE);
- glutInitWindowSize(500, 500);
- glutInitWindowPosition(1,1);
- our $WinID = glutCreateWindow("Curve_Vic");
- &init();
- glutDisplayFunc(\&display);
- glutReshapeFunc(\&Reshape);
- glutKeyboardFunc(\&hitkey);
- glutIdleFunc(\&idle);
- glutMainLoop();
- }
复制代码
作者: CrLf 时间: 2015-3-19 12:28
膜拜
作者: 523066680 时间: 2015-3-19 12:37
本帖最后由 523066680 于 2015-3-19 12:38 编辑
回复 2# CrLf
在某个文艺社区溜达的时候得知有一种可以做UI动画的软件叫做After Effect (一般配置还跑不起-_-)
效果请看:
http://onedesigner.lofter.com/post/28cbcd_4118d8a
http://onedesigner.lofter.com/post/28cbcd_42b6492
作者: CrLf 时间: 2015-3-19 13:00
回复 3# 523066680
妈的,仔细一看是 ae,ae我也会好吗
作者: 523066680 时间: 2015-3-19 14:25
回复 4# CrLf
好强…… AE做这个好像比写代码容易啊。可惜我电脑跑不动……
作者: CrLf 时间: 2015-3-19 14:36
回复 5# 523066680
要是 ae 更麻烦,adobe 公司可以去死了
作者: happy886rr 时间: 2016-5-12 19:36
梦幻般的感觉,看来我应该去学perl.平滑度极佳,完全是活的,希望能看到彩色水母.
作者: codegay 时间: 2016-5-12 19:40
回复 7# happy886rr
进我安利的坑,别跑
作者: codegay 时间: 2016-5-12 20:02
本帖最后由 codegay 于 2016-5-12 20:17 编辑
Processing 是一门主要做多媒体交互的。有很多很酷作品。
网上的作品展示有分形动图,
数据可视化,
多媒体交互 http://i.youku.com/u/UMzY0MDQyODIw
这里有一些作品 http://ravenkwok.com/
像这种的也有http://www.tudou.com/programs/view/V4QVzwcPe3Q/
作者: happy886rr 时间: 2016-5-12 20:19
回复 8# codegay
我都只学个皮毛,要精通没个一年很难.if exist善于用脚本语言展现动态美,蕴含许多巧妙设计.不借助软件工具,单靠脚本去实现动画.
作者: codegay 时间: 2016-5-12 20:31
回复 10# happy886rr
脚本和语言也只是工具啊。
作者: 523066680 时间: 2016-9-26 15:34
本帖最后由 523066680 于 2016-9-26 17:28 编辑
回复 9# codegay
前段时间接触过Processing,好像是依赖JAVA环境的,光是开个IDE就卡得出翔,连运行实例的心情都没了。
果断放弃。
回复 7# happy886rr
Perl 还是适合文本操作,恩。除非对Perl的代码风格有好感,否则不建议用Perl做太多别的事情。
Ruby好像不错,但是一直没去深入。不过真正要做点应用的话,我觉得还是应该上C#或C++
欢迎光临 批处理之家 (http://www.bathome.net/) |
Powered by Discuz! 7.2 |