Android实现SoulApp星球效果
SoulApp的星球看起来太炫酷了!!!
啥也不说先上图:
Github传送门 biu biu biu ~~~
基础知识
首先得拿出我们的数学知识:
- 球坐标系(r,θ,φ)与直角坐标系(x,y,z)的转换关系:
x = rsinθcosφ.
y = rsinθsinφ.
z = rcosθ.
Q:What!为什么要整个球坐标系啊?
A:因为星球嘛,位置信息当然球坐标系更加简单额。
实现思路
核心算法来自:3dTagCloudAndroid
在此基础上做了些修改后的效果
1. 获取均匀分布点坐标:
for (int i = 1; i < count + 1; i++) {// 平均(三维直角得Z轴等分[-1,1]) θ范围[-π/2,π/2])phi = Math.acos(-1.0 + (2.0 * i - 1.0) / count);theta = Math.sqrt(count * Math.PI) * phi;
}
2. 三维坐标
planetModelCloud.get(i - 1).setLocX((float) (radius * Math.cos(theta) * Math.sin(phi)));
planetModelCloud.get(i - 1).setLocY((float) (radius * Math.sin(theta) * Math.sin(phi)));
planetModelCloud.get(i - 1).setLocZ((float) (radius * Math.cos(phi)));
3. 坐标旋转
三维空间中的旋转变换比二维空间中的旋转变换复杂。除了须要指定旋转角外,还需指定旋转轴。
若以坐标系的三个坐标轴x,y,z分别作为旋转轴,则点实际上仅仅在垂直坐标轴的平面上作二维旋转。此时用二维旋转公式就能够直接推出三维旋转变换矩阵。
规定在右手坐标系中,物体旋转的正方向是右手螺旋方向,即从该轴正半轴向原点看是逆时针方向。
绕X轴
绕Y轴
绕Z轴
/*** 返回角度转换成弧度之后各方向的值* <p>* 1度=π/180** @param mAngleX x方向旋转距离* @param mAngleY y方向旋转距离* @param mAngleZ z方向旋转距离*/
private void sineCosine(float mAngleX, float mAngleY, float mAngleZ) {double degToRad = (Math.PI / 180);sinAngleX = (float) Math.sin(mAngleX * degToRad);cosAngleX = (float) Math.cos(mAngleX * degToRad);sinAngleY = (float) Math.sin(mAngleY * degToRad);cosAngleY = (float) Math.cos(mAngleY * degToRad);sinAngleZ = (float) Math.sin(mAngleZ * degToRad);cosAngleZ = (float) Math.cos(mAngleZ * degToRad);
}
利用上面的矩阵计算旋转后的三维直角坐标:
// 绕x轴旋转
float rx1 = (planetModel.getLocX());
float ry1 = (planetModel.getLocY()) * cosAngleX + planetModel.getLocZ() * -sinAngleX;
float rz1 = (planetModel.getLocY()) * sinAngleX + planetModel.getLocZ() * cosAngleX;
// 绕y轴旋转
float rx2 = rx1 * cosAngleY + rz1 * sinAngleY;
float ry2 = ry1;
float rz2 = rx1 * -sinAngleY + rz1 * cosAngleY;
// 绕z轴旋转
float rx3 = rx2 * cosAngleZ + ry2 * -sinAngleZ;
float ry3 = rx2 * sinAngleZ + ry2 * cosAngleZ;
float rz3 = rz2;
// 将数组设置为新位置
planetModel.setLocX(rx3);
planetModel.setLocY(ry3);
planetModel.setLocZ(rz3);
4. 计算二维坐标(为了让二维面看的更均匀,per可以始终设置为1)
// 添加透视图
int diameter = 2 * radius;
float per = diameter / (diameter + rz3);
// 让我们为标签设置位置、比例和透明度
planetModel.setLoc2DX(rx3 * per);
planetModel.setLoc2DY(ry3 * per);
planetModel.setScale(per);
5. 触摸事件处理
- 单指移动旋转(根据手指移动位移计算出旋转距离)
// 单点触摸,旋转星球
float dx = event.getX() - downX;
float dy = event.getY() - downY;
if (isValidMove(dx, dy)) {mAngleX = (dy / radius) * speed * TOUCH_SCALE_FACTOR;mAngleY = (-dx / radius) * speed * TOUCH_SCALE_FACTOR;processTouch();downX = event.getX();downY = event.getY();}
延时执行
// 延时
handler.postDelayed(this, 30);
手指滑动旋转后,对旋转距离做递减操作
// 减速模式(均速衰减)
if (mode == MODE_DECELERATE) {if (Math.abs(mAngleX) > 0.2f) {mAngleX -= mAngleX * 0.1f;}if (Math.abs(mAngleY) > 0.2f) {mAngleY -= mAngleY * 0.1f;}
}
processTouch();
- 双指缩放
记录起始的缩放比和起始双指距离
if (event.getActionIndex() == 1) {// 第二个触摸点scaleX = getScaleX();startDistance = distance(event.getX(0) - event.getX(1),event.getY(0) - event.getY(1));return true;
}
双指移动的时候计算缩放比,并对缩放比做限制
// 双点触摸,缩放
float endDistance = distance(event.getX(0) - event.getX(1),event.getY(0) - event.getY(1));
// 缩放比例
float scale = ((endDistance - startDistance) / (endDistance * 2) + 1) * scaleX;
if (scale > 1.4f) {scale = 1.2f;
}
if (scale < 1) {scale = 1f;
}
setScaleX(scale);
setScaleY(scale);
6. 每个点的View和效果
- 点的大小/点的明暗度
点的大小缩放,根据透视距离计算即可;明暗度根据缩放计算 - 点的文字过长跑马灯
// 位移
if (isOverstep) {signDistanceX = signDistanceX + 2.5f;if (signDistanceX > maxSignRange) {signDistanceX = signWidth;}
}
// 昵称文字过长(跑马灯)
if (isOverstep) {canvas.drawText(sign, totalSignWidth - signDistanceX, signY, signPaint);} else {canvas.drawText(sign, signX, signY, signPaint);
}
- 点的闪动效果
// 设置阴影
if (hasShadow) {starPaint.setShadowLayer(shadowRadius, 1.0f, 1.0f, alpha);canvas.drawCircle(starCenterX, starCenterY, radius, starPaint);
}
......
// 忽大忽小
if (hasShadow) {if (isEnlarge) {shadowRadius += radiusIncrement;} else {shadowRadius -= radiusIncrement;}if (shadowRadius < 1) {shadowRadius = 1.0f;isEnlarge = true;} else if (shadowRadius > radius) {shadowRadius = radius;isEnlarge = false;}
}
差不多就只有这些了,具体的就看代码吧:
Github传送门 biu biu biu ~~~
最后
如果你有什么意见和反馈,欢迎到Github提issue(最喜欢别人提issue了)哈哈哈~
Android实现SoulApp星球效果相关推荐
- android行星动画,Android实现SoulApp星球效果
SoulApp的星球看起来太炫酷了!!! 啥也不说先上图: soul planet.gif 基础知识 首先得拿出我们的数学知识: 球坐标系(r,θ,φ)与直角坐标系(x,y,z)的转换关系: x = ...
- Android横向伸缩,Android 实现伸缩布局效果示例代码
最近项目实现下面的图示的效果,本来想用listview+gridview实现,但是貌似挺麻烦的于是就用flowlayout 来addview实现添加伸缩的效果,实现也比较简单. mainActivit ...
- Android实现左右滑动效果
本示例演示在Android中实现图片左右滑动效果. 关于滑动效果,在Android中用得比较多,本示例实现的滑动效果是使用ViewFlipper来实现的,当然也可以使用其它的View来实现.接下来 ...
- Android 卡片翻转动画效果
转载请标明出处:http://blog.csdn.net/android_mnbvcxz/article/details/78570594 Android 卡片翻转动画效果 前言 前端时间开发一款应用 ...
- android 3d渲染动画效果吗,Android如何实现3D效果
前言 前段时间读到一篇文章,作者通过自定义View实现了一个高仿小米时钟,其中的3D效果很是吸引我,于是抽时间学习了一下,现在总结出来,和大家分享. 正文 想要在Android上实现3D效果,其实并没 ...
- Android 实现ListView圆角效果
今天,简单讲讲如何实现使用 ListView显示圆角. 其实代码很多都可以解决,这是在网上搜索的一个解决的代码. 无论是网站,还是APP,人们都爱看一些新颖的视图效果.直角看多了,就想看看 ...
- Android带三角形的弹窗,Android实现三角形气泡效果方式汇总
在开发过程中,我们可能会经常遇到这样的需求样式: 这张图是截取京东消息通知的弹出框,我们可以看到右上方有个三角形的气泡效果,这只是其中一种,三角形的方向还可以是上.下.左.右. 通过截图可以发现,气泡 ...
- Android 雪花飘落动画效果 自定义View
在码农的世界里,优美的应用体验,来源于程序员对细节的处理以及自我要求的境界,年轻人也是忙忙碌碌的码农中一员,每天.每周,都会留下一些脚印,就是这些创作的内容,有一种执着,就是不知为什么,如果你迷茫,不 ...
- android开发界面 淡出,Android 界面淡出 淡入效果
Android 界面淡出 淡入效果: 下面是一个工具类: AnimFadeUtil.java /** * 处理界面的淡入和淡出的切换 * @author Bruce * */ public c ...
最新文章
- 如何在大一时候系统学习编程?
- iOS 绘制圆角矩形
- 我国将于今年春季发射空间站核心舱 空间站进入全面实施阶段
- Python 技术篇-利用pyperclip库实现读取写入剪切板,超简单
- LESSON 11.4 原理进阶:AdaBoost算法流程详解
- 时空上下文视觉跟踪(STC)算法的解读与代码复现
- 如何有效完成医学科研课题设计?
- python 窗口 网页 访问_同事用Python操控浏览器运行,引的妹子围观不止!
- 因为apple无法检查其是否包含恶意软件_新Linux恶意脚本——清理其他恶意软件后再感染...
- kodi刮削器 中文_教你PLEX插件播放4K不能使用KODI解码导致卡顿的解决办法
- 机器学习笔记(六) ---- 支持向量机(SVM)
- ASP.NET三层架构的优点和缺点
- RabbitMQ 学习开发笔记
- c语言除法的ns流程图,ns流程图(c语言ns流程图怎么画)
- Neo4j【有与无】【N6】Graph数据库内部
- 如何通过几何画板学这些定理
- C#Base64编码
- 单源最短路径算法java_数据结构 - 单源最短路径之迪杰斯特拉(Dijkstra)算法详解(Java)...
- 浏览器上享受《速度与激情》,开发者花 16 个月用 JavaScript 造了一款驾驶游戏,水里也能开车!
- 美团点评 Hadoop/Spark 系统实践