百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程网 > 正文

令人惊叹的复杂之美:如何做一个iOS分形App?

yuyutoo 2025-02-03 15:55 3 浏览 0 评论

CSDN移动将持续为您优选移动开发的精华内容,共同探讨移动开发的技术热点话题,涵盖移动应用、开发工具、移动游戏及引擎、智能硬件、物联网等方方面面。如果您想投稿、参与内容翻译工作,或寻求近匠报道,请发送邮件至tangxy#csdn.net(请把#改成@)。

本文出自:WeheartSwift,译文出自:开发技术前线,译者:alier1226

介绍

在这个教程中,我们会做一个可以渲染Mandelbrot Set的应用程序,我们可以缩放和平铺它来看分形那令人惊叹的复杂之美。最终的结果可查看小视频。

着色程序代码如下:

void main {
    #define iterations 128
    vec2 position = v_tex_coord; // gets the location of the current pixel in the intervals [0..1] [0..1]
    vec3 color = vec3(0.0,0.0,0.0); // initialize color to black
    vec2 z = position; // z.x is the real component z.y is the imaginary component
    // Rescale the position to the intervals [-2,1] [-1,1]
    z *= vec2(3.0,2.0);
    z -= vec2(2.0,1.0);
    vec2 c = z; 
    float it = 0.0; // Keep track of what iteration we reached
    for (int i = 0;i < iterations; ++i) {
        // zn = zn-1 ^ 2 + c
        // (x + yi) ^ 2 = x ^ 2 - y ^ 2 + 2xyi
        z = vec2(z.x * z.x - z.y * z.y, 2.0 * z.x * z.y);
        z += c;
        if (dot(z,z) > 4.0) { // dot(z,z) == length(z) ^ 2 only faster to compute
            break;
        }
        it += 1.0;
    } 
    if (it < float(iterations)) {
        color.x = sin(it / 3.0);
        color.y = cos(it / 6.0);
        color.z = cos(it / 12.0 + 3.14 / 4.0);
    }
    gl_FragColor = vec4(color,1.0);
}

你可以下载 起始版本跟着教程一起做,也可以在本文结尾找到最终版本的代码。

项目设置

Gamescene.sks文件里包含一个名为fractal的子画面,它填充了整个界面并且着色程序程序Fractal.fsh也附在它上。

  • Fractal.fsh包含了上面着色程序的代码;
  • GameViewController.swift包含了设置游戏场景的代码;
  • GameScene.swift为空。

如果你现在运行代码,你将会得到如下的结果:

请注意纵横比固定为3/2,我们需要先根据屏幕大小调节它。同时,由于画面是静态的,所以你不可能与它有任何方式的交互。

设置界面

我们将用一个透明的scrollview来处理平铺缩放。scrollview将自动跟踪我们的位置以及我们在分形中的缩放程度。

打开'Main.storyboard'文件,拖进去一个scrollview。将scrollview设置成fill the view,并对它的宽度,到顶部距离,到底部距离设置限制。

将scrollview的最大缩放程度设置为100000,意味着我们将可以把分享放大到十万倍!我们不能再放大更多了因为已经接近了`float`类型的准确极限。

拖一个view(画面)到scrollview里,它将用作处理缩放。这个view本身不会展示任何东西,我们将用到它的contentOffset和scrollView的zoom属性来更新我们的着色程序。要确保这个画面可以填满scrollView,并且设定好宽度,到顶部底部左右距离的限制。将画面的背景色设置为 Clear Color (透明色)。

接下来我们将连接我们所需要的outlet和scrollView的代理。给scrollView和scrollView的contentView拖进outlet。

class GameViewController: UIViewController, UIScrollViewDelegate  {
 
    @IBOutlet weak var contentView: UIView!
    @IBOutlet weak var scrollView: UIScrollView!
    ...
}

接下来我们去掉代理方法,并且实现
viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView?
这个方法

class GameViewController: UIViewController, UIScrollViewDelegate  {
    ...
    func scrollViewDidScroll(scrollView: UIScrollView) { 
    }
    func scrollViewDidZoom(scrollView: UIScrollView) {
    }
    func viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView? {
        return contentView
    }
    ...
}

向着色程序发送数据

着色程序可以从你的swift代码里的uniform变量里获得数据。uniform变量可以在SpriteKit编辑器里声明。那现在我们来声明一下uniform变量。

打开GameScene.sks文件,选择mandelbrote sprite。将insepctor拖到底部,在“Custom shader Uniforms”里添加两项:float类型的zoom,值为1, 以及vec2类型的offset。我们将用这两项uniform变量储存scrollView的contentOffset以及zoom属性。

注意:Xcode 6.3的uniform变量有bug。它不能直接在编辑器里赋值初始化,你必须在代码里初始化它们。

我们可以通过shader属性来获取节点上(node)着色程序,用 theuniformedName方法来从着色程序得到uniform变量。以下是我们获取zoom uniform变量的例子:

let zoomUniform = node.shader!.uniformNamed("zoom")!

当我们有了uniform变量后,我们可以通过它的属性来改变它的值。

var textureValue: SKTexture!
var floatValue: Float
var floatVector2Value: GLKVector2
var floatVector3Value: GLKVector3
var floatVector4Value: GLKVector4
var floatMatrix2Value: GLKMatrix2
var floatMatrix3Value: GLKMatrix3
var floatMatrix4Value: GLKMatrix4

在本教程里,我们只对 floatValuefloatVector2Value感兴趣。

例子:将zoom的值设置成2

zoomUniform.floatValue = 2

相关推荐

掌握这些CSS知识点,Coding如飞(css的基础知识)

...

CSS:绝对定位、相对定位、固定定位

绝对定位position:absolute...

探索CSS position属性(css position relative)

提示:点击上方"蓝色字体"↑可以订阅噢!摘要51RGB官方微信position是CSS中非常重要的一个属性,通过position属性,我们可以让元素相对于其正常位置,父元素或者浏览器窗口进行偏移。...

你要的CSS布局都在这里(css布局的几种方式)

大家好,我是三木。这篇文章,替大家汇总了css的布局方式,在每个布局的结尾附上了我认为比较好的文章链接,不仅仅可以当作学习资料,也可以当作方法的查询手册,以后开发的时候忘记了某个属性就来查查。看完推荐...

CSS 元素分类与水平居中(css内容水平居中)
CSS 元素分类与水平居中(css内容水平居中)

元素分类在讲解CSS布局之前,我们需要提前知道一些知识,在CSS中,html中的标签元素大体被分为三种不同的类型:块状元素、内联元素(又叫行内元素)和内联块状元...

2025-04-08 20:29 yuyutoo

CSS 定位详解(css定位例子)

CSS有两个最重要的基本属性,前端开发必须掌握:display和position。display属性指定网页的布局。两个重要的布局,我已经介绍过了:弹性布局flex[1]和网格布局grid[2]。本...

CSS精准定位布局——position(css定位position的定位有哪些,有那么特点?)

1简介上一篇文章,介绍了魔鬼属性——浮动布局。浮动布局比较灵活,但是不容易控制。而定位布局使用户精准定位页面中的任意元素成为可能。因此在实际开发中,大家应该灵活使用这两种布局方式,这样才可以更好地满...

浅谈position中absolute和relative

CSSposition属性中absolute和relative很容易让人弄混,基本的概念什么着,你去参考W3C,就不啰嗦了--------------------------------------...

Windows Phone新手开发教程(一)(windows开发ios app)

这是本系列的第1部分。在进行开发的过程之前,我将解释WindowsPhone的基础知识。第1部分涵盖了以下三个开发的基本主题:WindowsPhoneSDK的安装WindowsPhone用户界...

.NET界面开发控件DevExpress v15.2.8发布

以下是DevExpress15.2.8新增的一些功能,以及帮助文档描述。DXDiagramforWPFT353654-当界面上至少有一个item可见时,BringItemsIntoView...

「炫丽」从0开始做一个WPF+Blazor对话小程序

...

QT与C#:选择适合界面开发的最佳框架,并且附带精美案例

QT和C#都提供了丰富的界面开发工具和库,允许开发人员创建各种类型的用户界面。以下是QT和C#界面开发方面的一些对比:...

Windows Phone新手开发教程(二)(windows开发iphone应用)

这是本系列的第2部分。在这里我将讲解StackPanel和Grid元素。很多时候开发人员对于在何处放置包含StackPane或Grid元素的控制元件感到困惑。那么我们就来了解一些关于StackPane...

WPF MVVM嵌套绑定黑科技:父-子ListView深度交互终极指南

场景痛点:当ListView遇上"套娃式"数据绑定在复杂的WPF企业级开发中,我们经常会遇到这样的需求:在父级ListView的每一项中嵌套子ListView,且子控件需要访问父级数据上下文。这种"...

在 WPF 项目中使用 WPFDevelopers NuGet 包

...

取消回复欢迎 发表评论: