2016-09-09 11:51:44 PDUnderstand 阅读数 2471

做了一个关于立体图形3D动画和绘制图形的例子,效果如下:

这个是参照苹果官方文档和例子来写的,其中茶壶是根据点、颜色渲染、网格结构和灯光效果来绘制出来的。

再说实现步骤前我们需要了解一下概念:

GLKView:作为OpenGLES内容的呈现目标

GLKViewController: 内容呈现的控制和动画,视图管理和维护一个framebuffer,应用只需在framebuffer进行绘画即可

GLKView 和GLKViewController类提供一个标准的OpenGLES视图和相关联的呈现循环

EAGLContext:实现和提供一个呈现环境

GLuint、GLfloat:其实就是typedef int和float的别名,当我们编写代码时不要被这些苹果的别名给吓到。

GLKTextureLoader:提供从iOS支持的各种图像格式的源自动加载纹理图像到OpenGLES 图像环境的方式,并能够进行适当的转换,并支持同步和异步加载方式

GLKMatrix4:一个unit共用体,是一个4*4的矩阵。

GLKBaseEffect:OpenGL ES 1.1规范中的关键的灯光和材料模式

好了,还有其他的概念性的东西可以下方留言,我将进行回答,也可以自己谷歌。

1.将所需系统库导入工程


2.创建一个GLKViewController类。

重写一个继承类,然后将view改为GLKView。

@interface PDTeapotViewController : GLKViewController
{
    EAGLContext *context;    // 实现和提供一个呈现环境
    GLuint mode;
    // 茶壶
    GLfloat rot;
    // 正方体
    GLfloat cubePos[3];
    GLfloat cubeRot;
    GLuint cubeTexture;
}

@property (nonatomic, strong) PDTeapotBaseEffect *innerCircle;
@property (nonatomic, strong) PDTeapotBaseEffect *outerCircle;
@property (nonatomic, strong) PDTeapotBaseEffect *teapot;
@property (nonatomic, strong) NSMutableArray *cubeEffectArr;
@property (nonatomic, strong) PDMusicCube *musicCube;

@end
并且分别在类中创建效果路径、茶壶、正方体、和控制背景音乐。

- (void)viewDidLoad {
    [super viewDidLoad];
    
    context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
    // 创建环境失败,或者将当前线程环境设置失败
    if (!context || ![EAGLContext setCurrentContext:context]) {
        return;
    }
    GLKView *glView = (GLKView *)self.view;
    glView.context = context;
    glView.drawableDepthFormat = GLKViewDrawableDepthFormat16;
    
    mode = 1;
    glEnable(GL_DEPTH_TEST);
    
    // 创建效果路径
    self.innerCircle = [PDTeapotBaseEffect makeCircleWithNumOfSegments:circleSegments radius:pathCircleRadius];
    self.outerCircle = [PDTeapotBaseEffect makeCircleWithNumOfSegments:circleSegments radius:pathOutCircleRadius];
    
    // 创建茶壶
    self.teapot = [PDTeapotBaseEffect makeTeapot];
    
    // 创建正方体
    self.cubeEffectArr = [PDTeapotBaseEffect makeCube];
    
    [self setUpCubeEffect];
    
    [self setUpMusicCube];
}
3.创建一个材料和效果类

#import "PDTeapotBaseEffect.h"

用来创建图形

<span style="font-size:12px;">#define kTeapotScale		1.8
#define kCubeScale			0.12
#define kButtonScale		0.1

#define kButtonLeftSpace	1.1

#define	DegreesToRadians(x) ((x) * M_PI / 180.0)

#define BUFFER_OFFSET(i) ((char *)NULL + (i))

static const CGFloat pathCircleRadius = 1.0;  // 运动路径内环
static const CGFloat pathOutCircleRadius = 1.1;  // 运动路径外环
static const GLuint circleSegments = 36;

// 效果类
@interface PDTeapotBaseEffect : NSObject

@property (nonatomic, strong) GLKBaseEffect *effect; // 效果类,灯光和材料模式效果
@property (nonatomic, assign) GLuint vertexArray;    // GLuint基础类型
@property (nonatomic, assign) GLuint vertexBuffer;
@property (nonatomic, assign) GLuint normalBuffer;


/**
 *  创建运动轨迹
 */
+ (instancetype)makeCircleWithNumOfSegments:(GLuint)segments radius:(GLfloat)radius;

/**
 *  创建茶壶
 */
+ (instancetype)makeTeapot;

/**
 *  创建正方体
 */
+ (NSMutableArray *)makeCube;

/**
 *  背景音乐的播放
 */
+ (void)musicBack;</span>


例如创建一个茶壶代码:

PDTeapotBaseEffect *teapot = [[PDTeapotBaseEffect alloc] init];
    GLKBaseEffect *effect = [[GLKBaseEffect alloc] init];
    // 材料
    effect.material.ambientColor = GLKVector4Make(0.4, 0.8, 0.4, 1.0);
    effect.material.diffuseColor = GLKVector4Make(1.0, 1.0, 1.0, 1.0);
    effect.material.specularColor = GLKVector4Make(1.0, 1.0, 1.0, 1.0);
    effect.material.shininess = 100.0;
    // 光
    effect.light0.enabled = GL_TRUE;
    effect.light0.ambientColor = GLKVector4Make(0.2, 0.2, 0.2, 1.0);
    effect.light0.diffuseColor = GLKVector4Make(0.2, 0.7, 0.2, 1.0);
    effect.light0.position = GLKVector4Make(0.0, 0.0, 1.0, 0.0);
    
    GLuint vertexArray, vertexBuffer, normalBuffer;
    
    glGenVertexArraysOES(1, &vertexArray);
    glBindVertexArrayOES(vertexArray);
    
    // 位置
    glGenBuffers(1, &vertexBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(teapot_vertices), teapot_vertices, GL_STATIC_DRAW);
    
    glEnableVertexAttribArray(GLKVertexAttribPosition);
    glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
    
    glGenBuffers(1, &normalBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, normalBuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(teapot_normals), teapot_normals, GL_STATIC_DRAW);
    
    glEnableVertexAttribArray(GLKVertexAttribNormal);
    glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
    
    glBindVertexArrayOES(0);
    
    teapot.effect = effect;
    teapot.vertexArray = vertexArray;
    teapot.vertexBuffer = vertexBuffer;
    teapot.normalBuffer = normalBuffer;
    return teapot;

4.利用glkView:drawInRect:函数做绘制和重绘

关于glkView:drawInRect:我要解释一下:

使用GLKit视图绘制OpenGL内容需要三个子步骤:准备OpenGLES基础;发布绘制命令;呈现显示内容到Core Animation。       GLKit类本身已经实现了第一个和第三个步骤,用户只需实现第二个步骤,在视图的方法drawRect或视图的代理对象的glkView:drawInRect:中调用适当的OpenGLES绘制命令进行内容绘制。

代码如下(由于代码比较多,我将部分粘贴,其余部分参照我的github例子 ps:下载时给颗星最好了。。。。):

<span style="font-size:12px;">#pragma mark - 重绘
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
    glClearColor(0.0, 0, 0, 1.0);
    glClearDepthf(1.0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
    GLfloat aspectRatio = (GLfloat)(view.drawableWidth) / (GLfloat)(view.drawableHeight);
    GLKMatrix4 projectionMatrix = GLKMatrix4MakeOrtho(-1.0f, 1.0f, -1.0f/aspectRatio, 1.0f/aspectRatio, -10.0f, 10.0f);
    projectionMatrix = GLKMatrix4Rotate(projectionMatrix, DegreesToRadians(-30.0f), 0.0f, 1.0f, 0.0f);
    
    // set the projection matrix
    self.innerCircle.effect.transform.projectionMatrix = projectionMatrix;
    self.outerCircle.effect.transform.projectionMatrix = projectionMatrix;
    self.teapot.effect.transform.projectionMatrix = projectionMatrix;
    for (int f=0; f<6; f++)
        ((PDTeapotBaseEffect *)self.cubeEffectArr[f]).effect.transform.projectionMatrix = projectionMatrix;
    
    glBindVertexArrayOES(self.innerCircle.vertexArray);
    [self.innerCircle.effect prepareToDraw];
    glDrawArrays (GL_LINE_LOOP, 0, circleSegments);
    
    glBindVertexArrayOES(self.outerCircle.vertexArray);
    [self.outerCircle.effect prepareToDraw];
    glDrawArrays (GL_LINE_LOOP, 0, circleSegments);
    
    [self drawTeapotAndUpdatePlayback];
    
    [self drawCube];
}</span>
好了,关于整个项目其他不动的地方可以参照, 图像编程总结
下面是大家最想要的   github源码



2018-01-23 16:52:08 Fantasy_Jun 阅读数 1465

一,预备工作

首先要在IOS上开发AR需要版本在ios11.0及以上,xcode9及以上,你才能进行开发

二,创建项目

打开Xcode,选择ARKit项目模板:


建好后会有一台默认的飞机模型出现在镜头里

三,实现3D立方体

替换的viewDidLoad中的代码如下:

- (void)viewDidLoad {
    [super viewDidLoad];
/*    
    //存放所有3D集合体的容器
    SCNScene *scene = [SCNScene scene];
    
    //想要绘制的3D立方体
    SCNBox *boxGeometry = [SCNBox boxWithWidth:0.1 height:0.1 length:0.1 chamferRadius:0.0];
    
    //将几何体包装为node以便添加
    SCNNode *boxNode = [SCNNode nodeWithGeometry:boxGeometry];
    
    //把box放在摄像头正前方
    boxNode.position = SCNVector3Make(0, -0.25, -0.5);
    
    //rootNode是一个特殊的node,是所有node的起始点
    [scene.rootNode addChildNode:boxNode];
    
    //创建渲染器
    SCNMaterial *material = [SCNMaterial material];
    material.diffuse.contents = [UIColor redColor];   //  渲染器可以决定怎样渲染,这个 contents 属性可以设置很多东西,UILabel, UIImage,甚至 AVPlayer 都可以
    //用渲染器对几何图形进行渲染
    boxGeometry.materials = @[material];
    
    //将scene赋给view
    _sceneView.scene = scene;
    
    //光效
    _sceneView.automaticallyUpdatesLighting = YES;
    
    
}
然后就大功告成啦~
效果如下图:


参考链接:https://www.jianshu.com/p/396a0d1c16f9(Swift)


2016-04-07 14:29:02 chinnyman 阅读数 2065

如何画一个饼图, 来实现数据展示的可视化

  • PieChartView.h
#import <UIKit/UIKit.h>

@interface PieChartView : UIView

@end
  • PieChartView.m
#import "PieChartView.h"

@implementation PieChartView

- (void)drawRect:(CGRect)rect {

    CGFloat w = self.bounds.size.width;
    CGFloat h = self.bounds.size.height;

    //数据数组
    NSArray *array = @[@25,@30,@45];
    //颜色数组
    NSArray *colorArray = @[[UIColor redColor], [UIColor greenColor], [UIColor yellowColor]];

    CGContextRef ctx =UIGraphicsGetCurrentContext();

    //中心点
    CGPoint center = CGPointMake(w * 0.5, h * 0.5);
    //半径
    CGFloat radius = w * 0.5 - 5;

    //起点角度
    CGFloat startA = 0;
    //终点角度
    CGFloat endA = 0;
    //扫过角度范围
    CGFloat angle = 0;

    for (int i = 0; i < array.count; i ++) {

        startA = endA;
        angle = [array[i] integerValue] / 100.0 * M_PI * 2;
        endA = startA + angle;

        //弧形路径
        //clockwise: 是否是按照时钟的方向旋转(是否顺时针)
        UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center radius:radius startAngle:startA endAngle:endA clockwise:YES];
        //连接中心, 构成扇形
        [path addLineToPoint:center];

        //填充颜色
        [(UIColor *)colorArray[i] set];

        CGContextAddPath(ctx, path.CGPath);

        // 将上下文渲染到视图
        CGContextFillPath(ctx);
    }
}

@end
2019-09-23 17:06:30 llhf688 阅读数 67

Sketch是一款为设计师量身定做的优美界面和强大工具兼有的专业绘图工具。制作出漂亮的图形是一件很有挑战性的事情,你所需要的是一款精心设计的应用 程序。此次小编带大家用sketch绘制3D球体。

一、创建画板+镂空球体

1、快捷键A,创建画布800*600

2、快捷键O,绘制一个直径为340的圆形,Fills为径向渐变填充,色值为(#E2CFFF-#84739D-#403055),如下图:

3、快捷键O首先绘制一个椭圆形(160*112),旋转角度55,再复制两个右边、下面各一个,调整好位置,选中这四个图形,执行剪切命令,得到一个镂空圆形如下图:

二、创建小球体

1、接着我门再绘制一个直径为230的圆形,颜色填充为径向渐变,色值为(#FFFFFF-#F9B5B5-#F15454)图层置于大圆之下,如下图:

2、大致形出来了,接着我们开始塑造球的体积感,即球体的厚度表现,首先还是,画个圆,然后再来一个,通过剪切,我们得到所需形状,如下图:

3、看着有点奇怪,别慌,先把它图层位置换换放到小圆的下,拉一个线性渐变,色值为(#CDA7E2-#5E0000)如下图:

4、是不是有点样子了,然后再复制出来把其他两个位置摆放好,颜色深浅稍微拉点,就离完工不远了!

三、细节塑造

1、再给球体分别加上光感,使表面看着更加光滑透亮,圆圆圆还是圆,对!就是它快捷键O绘制一个318的正圆,颜色为白色径向渐变,透明度从(25%-0%)

2、继续为小圆添加光面,如图所示,光源方向左上角入,小圆因为在内,受光面积略小,仅上半部,所以仅需留半圆即可,颜色为白色径向渐变,透明度从(100%-0%)

3、依然是习惯,换背景,加投影,哈哈哈这个大家随意即可!

以上就是小编为大家带来的Sketch实例教程:绘制3D球体。

2017-07-31 11:06:12 ZCMUCZX 阅读数 292

饼图

 NSArray * array=@[@0.25,@0.35,@0.3,@0.1];
    CGFloat start=0.0;
    CGFloat end=0.0;
    for(int i=0;i<array.count;i++)
    {
        //结束的位置等于起始的位置加大小
        end=2*M_PI*[array[i] floatValue]+start;
        UIBezierPath * path=[UIBezierPath bezierPathWithArcCenter:CGPointMake(100, 100) radius:100 startAngle:start endAngle:end clockwise:YES];
        //画一个从终点到圆心的线
        [path addLineToPoint:CGPointMake(100, 100)];
        [[UIColor colorWithRed:((float)arc4random_uniform(256)/255.0)green:((float)arc4random_uniform(256)/255.0) blue:((float)arc4random_uniform(256)/255.0) alpha:1] set];
        [path fill];
        //下一次的起点等于上一次的终点
        start=end;
    }



柱状图

  NSArray * array=@[@0.7,@1,@0.3,@0.5,@0.6];
    for(int i=0;i<array.count;i++)
    {
    CGFloat width=rect.size.width/((2*array.count)-1);
    CGFloat height=[array[i] floatValue]*rect.size.height;
    CGFloat x=i*2*width;
    CGFloat y=rect.size.height-height;
        UIBezierPath * path=[UIBezierPath bezierPathWithRect:CGRectMake(x, y, width, height)];
        //设置随机的颜色
     [[UIColor colorWithRed:((float)arc4random_uniform(256)/255.0)green:((float)arc4random_uniform(256)/255.0) blue:((float)arc4random_uniform(256)/255.0) alpha:1] set];
       //渲染
        [path fill];

一个 iOS 饼图控件

阅读数 2033

iOS动画系列一

阅读数 467

三 iOS之 画饼图

阅读数 302

没有更多推荐了,返回首页