在unity向量空间内绘制几何(1):通过将极坐标转换为直角坐标,绘制阿基米德螺线,对数螺线与玫瑰线等几何图形

本文介绍如何使用极坐标公式生成各种几何图形,包括阿基米德螺旋线、对数螺旋线、心脏线及玫瑰线等。文章提供了将这些极坐标公式转化为代码的方法,以及通过调整参数来改变图形形状的具体步骤。

一些基础几何图形的极坐标公式

极坐标内的每个点都有两个参数: r, 与 θ\thetaθ。r为此点到极点(中心点)的距离,θ\thetaθ 为此点到极点的线段与极轴(类似x轴)的夹角。

很多几何图形公式都可以用极坐标简洁的表示,例如:

阿基米德螺旋线:(公式1) r=a+b*θ\thetaθ
这里写图片描述

对数螺旋线:(公式2)r=a∗eb∗θr=a*e^{b*\theta}r=aebθ
这里写图片描述

心脏线:(公式3)r=a(1−sin⁡∗θ)r=a(1-\sin*\theta)r=a(1sinθ)
这里写图片描述
玫瑰线:(公式4)r=cos⁡(k∗θ)+cr=\cos(k*\theta)+cr=cos(kθ)+c
这里写图片描述

以上公式中的a,b,c,k都是常数,可以用来控制图形的形状。
已知了r 与 θ\thetaθ 的关系,那么只要依次算出θ\thetaθ从0至2π\piπ相对应的r值,我们就能得出一个连续的极坐标(r, θ\thetaθ)数组。

极坐标与直角坐标的转换函数

直角坐标xy与r,θ\thetaθ的关系:
公式5:
x=r∗cos⁡(θ)x=r*\cos(\theta)x=rcos(θ)
y=r∗sin⁡(θ)y=r*\sin(\theta)y=rsin(θ)

尝试将公式5与各极坐标公式结合:

public Vector3[] GeneratePolarRoses(int points,Vector3 centre,float k,float c,float scale){
		
		Vector3[] coordinates=new Vector3[points]; 
		//将2π均分为points份,并依次赋予theta
		float theta=2f*Mathf.PI/points;
		float radius;
		for(int t=0;t<points;t++){
			//公式4转换为代码,算出theta从0至2π每个角度的r值
			radius=Mathf.Cos(k*theta)+c;
			//公式5转换为代码,既是将极坐标转换为直角坐标
			coordinates[t]=new Vector3(scale*radius*Mathf.Cos(theta)+centre.x,scale*radius*Mathf.Sin(theta)+centre.y,0f);
			theta+=2f*Mathf.PI/points;
		}
		return coordinates;
	}

该函数将会返回一个玫瑰线坐标点数组,参数points为返回的数组长度,centre为图形中心点位置坐标。参数k必须为整数,当为奇数时,花瓣数量为k,当为偶数时,花瓣数量为2k。参数c也会影响图形形状,当为0-1之间时,将会产生类似花蕊的效果。参数scale可以设置图形整体大小。

下面生成阿基米德螺旋线与对数螺旋线的函数的思路与玫瑰线基本相同,唯一不同的是增加了一个参数circles可以设置螺旋的圈数:

	public Vector3[] GenerateArchimedeanSpirals(int points,Vector3 centre,int circles,float a,float b){

		Vector3[] coordinates=new Vector3[points]; 

		float radius;
		//调整角度的分配模式,circles为螺旋的圈数
		float theta=2f*Mathf.PI/points*circles;
		for(int t=0;t<points;t++){
			//公式1
			radius=a+b*theta;	
			//公式5	
			coordinates[t]=new Vector3(radius*Mathf.Cos(theta)+centre.x,radius*Mathf.Sin(theta)+centre.y,0f);
			theta+=2f*Mathf.PI/points*circles;
		}
		return coordinates;
	}

对数螺线:

	public Vector3[] GenerateLogarithmicSpirals(int points,Vector3 centre,int circles,float a,float b){

		Vector3[] coordinates=new Vector3[points]; 

		float radius;
		float theta=2f*Mathf.PI/points*circles;
		for(int t=0;t<points;t++){
			//公式2
			radius=a*Mathf.Exp(b*theta);
			coordinates[t]=new Vector3(radius*Mathf.Cos(theta)+centre.x,radius*Mathf.Sin(theta)+centre.y,0f);
			theta+=2f*Mathf.PI/points*circles;
			scales[t]=radius;
		}
		return coordinates;
	}

对数螺旋线
GenerateLogarithmicSpirals效果图,a为0.1,b为0.1,共13圈的对数螺线,每个坐标点放置了不同scale的UI图。

### 使用 Android Vector Drawable 设置坐标 在 Android 中,`<vector>` XML 文件用于定义矢量图形。这些图形通过路径数据来绘制形状,并允许指定各种属性以控制其外观和行为。 对于 `<path>` 元素来说,可以通过 `android:pathData` 属性设置具体的绘图指令。此属性采用一种紧凑的字符串表示法,其中包含了移动到特定位置、画线以及曲线等命令。为了理解如何设定坐标,在这里提供一些基本概念: - **M/m**: 移动笔触起点到绝对(x,y) 或相对偏移(dx,dy)[^2]。 - **L/l**: 绘制线到绝对终点(x,y) 或相对于当前点的偏移(dx,dy)[^2]。 - **H/h,V/v**: 水平或垂直方向上绘制一条线至给定的位置[x|y][^2]。 - **C/c,S/s,Q/q,T/t,A/a,Z/z**: 定义贝塞尔曲线和其他类型的线条。 具体而言,当想要调整某个节点的位置时,可以在对应的命令后面加上新的坐标值。例如,“M10 10 L20 20”意味着先将起始点移到(10,10),再从此处向右下方画一直线到达(20,20)。 另外值得注意的是,整个矢量图像还可以通过修改根元素 `<vector>` 的 `android:viewportWidth` 和 `android:viewportHeight` 来改变视口尺寸,这会影响所有子级路径的实际显示比例[^3]。 最后,关于坐标的实际应用可以参见如下代码片段展示了一个简单的三角形创建过程: ```xml <vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" android:height="24dp" android:viewportWidth="24" android:viewportHeight="24"> <!-- 创建一个填充颜色为白色的三角形 --> <path android:fillColor="#FFFFFF" android:pathData="M9.9 2.1 l9.9 9.9 h-6.37 v7.73 z"/> </vector> ``` 上述例子中,`M9.9 2.1` 表示从 (9.9, 2.1) 开始绘制;接着 `l9.9 9.9` 是指沿水平轴正方向前进 9.9 单位长度的同时也沿着垂直轴向上增加同样的距离形成斜边;之后使用 `h-6.37` 向左返回一部分宽度并最终用 `v7.73` 上升完成闭合多边形。 #### 关键参数解释 - `android:width`, `android:height`: 设定了该矢量资源默认渲染出来的物理像素大小(dp单位)[^4]。 - `android:viewportWidth`, `android:viewportHeight`: 定义了逻辑上的工作区范围,即所谓的“视窗”,它决定了内部路径所使用的坐标系尺度。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值