跳转到内容

分形/计算机图形技术/2D/变换

来自维基教科书,自由的教科书,开放的世界

平面变换

  • 变换
  • 投影
    • 制图地图投影[1](在 3D 到 2D 图形的情况下)[2]
  • 映射

2D 光栅图形中的映射是一个复杂的函数 ,它将复平面映射到复平面。


它被实现为点变换。

它通常表示为


其中

  • 是复平面的一个点(输入)
  • 是图像复平面的一个点(输出 = 结果)

示例代码

[编辑 | 编辑源代码]

例如,墨卡托:[3]


function Spherical_mercator(x, y) {
  return [x, Math.log(Math.tan(Math.PI / 4 + y / 2))];
}

function transverseMercatorRaw(lambda, phi) {
  return [log(tan((halfPi + phi) / 2)), -lambda];
}

transverseMercatorRaw.invert = function(x, y) {
  return [-y, 2 * atan(exp(x)) - halfPi];
};

如果有人使用离散几何(多边形和折线),那么投影就很难实现。必须在精度和性能之间取得平衡。 [4]



// https://github.com/adammaj1/Mandelbrot-Sets-Alternate-Parameter-Planes/blob/main/src/lcm/d.c
// projection from p to c 
complex double map_parameter(const ParameterTypeT ParameterType, const complex double parameter){

	
	complex double p; 
	// plane transformation 
	switch(ParameterType){
	
		case c_identity :{p = parameter;  break;}
		
		case c_inverted :{p = 1.0/parameter; break;}
		
		case c_parabola :{p = 0.25+ 1.0/parameter; break;}
		
		case c_Myrberg_type :{p = cf - 1.0/parameter; break;}
		
		case c_inverted_2_type :{p = -2.0 + 1.0/parameter; break;}
		
		case c_exp :{p = cf + cexp(parameter) ; break;} // here one can change cf to get different image 
		
		
		case lambda_identity :{ p = parameter;  break;}
		
		case lambda_inverted_type :{p = 1.0/parameter; break;}
		
		case lambda_inverted_1_type :{p =1.0+ 1.0/parameter; break;}
		
		default: {p = parameter;}
	}

映射分类

  • 基于对象的映射(图像对象是具有相同整数值的连接像素集)
  • 基于像素的映射


2D 图形中的变换(映射)

  • 基本类型
  • 复合变换[5]


矩阵的使用

  • 不使用矩阵(使用函数)
  • 使用矩阵

坐标


  • "矩阵乘法不满足交换律。变换的顺序至关重要——旋转后平移与平移后旋转截然不同" [6]


实现




仿射变换

[编辑 | 编辑源代码]

为了用矩阵表示仿射变换,我们可以使用齐次坐标。这意味着将 2 向量 (x, y) 表示为 3 向量 (x, y, 1),更高维度也是如此。

2D 仿射变换矩阵



变换名称 仿射矩阵 示例
恒等(变换到原始图像)
平移
反射
缩放
旋转
其中 θ = π/6 =30°
剪切

仿射变换适用于将两幅或多幅图像对齐(配准)的配准过程。一个图像配准的例子是全景图像的生成,全景图像是多幅拼接在一起的图像的产物。




缩放或调整大小

[编辑 | 编辑源代码]

关于原点按比例因子缩放物体

 


变为


缩放

  • 均匀(在缩放时保持物体的比例):sx = sy
  • 非均匀:sx != sy


在保持固定中心点的情况下调整物体大小 = 关于其自身中心缩放物体

  • 宽度' = 宽度 * sx
  • 高度' = 高度 * sy
  • 计算中心点的角坐标


复数平移是一个映射[7]

其中

使用这种系统,平移可以用矩阵乘法表示。 函数形式

 
 

变为

旋转

[edit | edit source]

绕原点以角度 θ 逆时针(正方向)旋转的函数形式为

 
.  

写成矩阵形式,就变成了:[8]


类似地,绕原点顺时针(负方向)旋转的函数形式为

 
 

矩阵形式为


这些公式假设x轴指向右侧,y轴指向上方。



归一化坐标下的逆时针旋转矩阵



没有矩阵的 C 代码

 
/* 

C program to rotate an object by a given angle about a given point
gcc r.c -Wall -Wextra -lm
./a.out
*/

#include <stdio.h>
#include <math.h> 
#include <complex.h> 		// complex numbers : https://stackoverflow.com/questions/6418807/how-to-work-with-complex-numbers-in-c


//The sin() function returns the value in the range of [-1, 1]

/*
https://stackoverflow.com/questions/2259476/rotating-a-point-about-another-point-2d 
First subtract the pivot point (cx,cy), then rotate it (counter clock-wise), then add the point again.
*/


 complex double rotate_point(const complex double center, const double angle_in_radians, const complex double point )
{
	// translate point to center
	complex double translated_point = creal(point) - creal(center)  + (cimag(point) - cimag(center))*I;

	// rotate point counter clock-wise by a given angle about a given pivot point ( center)
	double s = sin(angle_in_radians);
	double c = cos(angle_in_radians);
	complex double new_point = creal(translated_point) * c - cimag(translated_point) * s + (creal(translated_point) * s + cimag(translated_point) * c)*I;

	// translate point back
	new_point = creal(new_point) + creal(center) +(cimag(new_point) + cimag(center))*I;
  
  
	return new_point;
}

#define kMax 6

// center, angle_rad, point 
double examples[kMax][5] = {
		{50,-50, -0.7853982, 100,100 },
		{50,-50, -0.7853982, 100,200 },
		{50,-50, -0.7853982, 200,200 },
		{0,0, 1.570796, 100,100}, 
		{0,0, 1.570796, 150,200}, 
		{0,0, 1.570796, 200,200} 

};

int main(void){

	
	
	
	int k;
	
	
	
	complex double center ;
	double angle_r ; 
	complex double point ;
	complex double rotated_point;
	
	
	for (k=0; k<kMax; ++k){
		center = examples[k][0] + examples[k][1] * I ;
		angle_r = examples[k][2]; 
		point = examples[k][3] + examples[k][4] * I ;
		rotated_point = rotate_point(center, angle_r, point );
		fprintf(stdout, "point %f%+f*I rotated about %f%+f*I  by %f radians is %f%+f*I \n", creal(point), cimag(point), creal(center), cimag(center), angle_r, creal(rotated_point), cimag(rotated_point));
		}
	
	 


	return 0;
}

输出

point 100.000000+100.000000*I rotated about 50.000000-50.000000*I  by -0.785398 radians is 191.421359+20.710673*I 
point 100.000000+200.000000*I rotated about 50.000000-50.000000*I  by -0.785398 radians is 262.132040+91.421348*I 
point 200.000000+200.000000*I rotated about 50.000000-50.000000*I  by -0.785398 radians is 332.842715+20.710668*I 
point 100.000000+100.000000*I rotated about 0.000000+0.000000*I  by 1.570796 radians is -99.999967+100.000033*I 
point 150.000000+200.000000*I rotated about 0.000000+0.000000*I  by 1.570796 radians is -199.999951+150.000065*I 
point 200.000000+200.000000*I rotated about 0.000000+0.000000*I  by 1.570796 radians is -199.999935+200.000065*I 

其他有趣的映射

[edit | edit source]


例子:[9][10]

共形映射

[edit | edit source]
  • "共形映射保持角度,并将无穷小圆映射到无穷小圆。 非共形映射将无穷小圆映射到无穷小椭圆(或更糟)。" Claude Heiland-Allen
  • "复函数 在无穷远处是共形的,如果函数 在 0 处是共形的。 这等同于通常的关于共形的定义,即在大小和方向(顺时针/逆时针)方面保持角度不变,如果你将 视为在黎曼球体的“北极”处保持角度不变。"[22]

共形映射

共形映射词典,作者:John H. Mathews 和 Russell W. Howell(2008 年)

制图地图投影

[edit | edit source]

圆柱投影

[edit | edit source]
球体到圆柱的正切(赤道)投影的几何形状。

圆柱投影(或圆柱 p.)将球体(无极点)映射到圆柱上[23][24]

茹科夫斯基变换(映射)

[edit | edit source]

描述 

域着色或复相图

[编辑 | 编辑源代码]

复杂函数的可视化

模形式

[编辑 | 编辑源代码]

黎曼映射

[编辑 | 编辑源代码]

参考文献

[编辑 | 编辑源代码]
  1. 维基百科中的地图投影
  2. observable: plot-projections
  3. 维基百科中的横轴墨卡托投影
  4. : JavaScript 中的地理投影、球形形状和球面三角学
  5. geeksforgeeks : 2D 图形中的复合变换
  6. Nicolas Holzschuch 博士的 2D 变换和齐次坐标 开普敦大学
  7. Terr, David. "复杂平移." 来自 MathWorld--Wolfram Web 资源,由 Eric W. Weisstein 创建。
  8. http://ocw.mit.edu/courses/aeronautics-and-astronautics/16-07-dynamics-fall-2009/lecture-notes/MIT16_07F09_Lec03.pdf Template:Bare URL PDF
  9. opentextbc.ca: 地理信息本质
  10. wolfram : ComplexFunctionsAppliedToASquare
  11. scikit-image.org 文档: swirl
  12. Alexandre Bernardino 的对数极坐标映射
  13. Weisstein, Eric W. "抛物柱面坐标." 来自 MathWorld--Wolfram Web 资源
  14. Weisstein, Eric W. "抛物线坐标." 来自 MathWorld--Wolfram Web 资源。
  15. Bjørnar Steinnes Luteberget 的共形映射数值逼近
  16. processing : transform2d
  17. 看起来圆形的正方形: Saul Schleimer 和 Henry Segerman 的球面图像变换
  18. fractalforums inflection-mappings
  19. theinnerframe : playing-with-circular-images
  20. theinnerframe: squaring-the-circle
  21. fractalforums: fractal-on-sphere
  22. math.stackexchange 问题: conformal-mappings-of-riemann-sphere
  23. Paul Bourke 编写的球面投影(立体投影和圆柱投影)
  24. Weisstein, Eric W. "圆柱投影." 来自 MathWorld--Wolfram Web 资源。
  25. johndcook : joukowsky-transformation
华夏公益教科书