三維空間中直角坐標與球坐標的相互轉換


三維直角坐標系

三維直角坐標系是一種利用直角坐標(x,y,z)來表示一個點 P 在三維空間的位置的三維正交坐標系

注:本文所討論的三維直角坐標系,默認其x-軸、y-軸、z-軸滿足右手定則(如右圖所示)。

在三維空間的任何一點 P ,可以用直角坐標(x,y,z)來表達其位置。如左下圖顯示了三維直角坐標的幾何意義:點P在x-軸、y-軸、z-軸上的投影距離分別為x、y、z。如右下圖所示,兩個點 P 與 Q 的直角坐標分別為(3,0,5)與(-5,-5,7) 。

球坐標系

球坐標系是一種利用球坐標(r,θ,φ)來表示一個點 P 在三維空間的位置的三維正交坐標系

 下圖描述了球坐標的幾何意義:原點O與目標點P之間的徑向距離為r,O到P的連線與正z-軸之間的夾角為天頂角θ,O到P的連線在xy-平面上的投影線與正x-軸之間的夾角為方位角φ

假設 P 點在三維空間的位置的三個坐標是 (r,\ \theta,\ \phi)。那么, 0 ≤ r 是從原點到 P 點的距離, 0 ≤ θ ≤ π 是從原點到 P 點的連線與正 z-軸的夾角, 0 ≤ φ < 2π 是從原點到 P 點的連線在 xy-平面的投影線,與正 x-軸的夾角。當 r=0 時,\theta 與 \phi 都一起失去意義。當 \theta = 0 或 \theta = \pi 時,\phi 失去意義。

三維空間下直角坐標與球坐標的相互轉換

直接坐標轉球坐標

{r}=\sqrt{x^2 + y^2 + z^2} 、

{\theta}=\arctan \left( \frac{\sqrt{x^2 + y^2}}{z} \right)=\arccos \left( {\frac{z}{\sqrt{x^2 + y^2 + z^2}}} \right) 、

{\phi}=\arctan \left( {\frac{y}{x}} \right) 。

球坐標轉直角坐標

x=r \sin\theta \cos\phi 、

y=r \sin\theta \sin\phi 、

z=r \cos\theta 。

基於Flex的坐標轉換實現

直角坐標定義類CartesianCoord.cs

package hans_gis.coord
{
	public class CartesianCoord
	{
		public var x:Number;
		public var y:Number;
		public var z:Number;
		
		static private var temp:CartesianCoord = CartesianCoord.ZERO;
		
		public function CartesianCoord(x:Number=0, y:Number=0, z:Number=0)
		{
			this.x = x;
			this.y = y;
			this.z = z;
		}
		
		public function clone():CartesianCoord
		{
			return new CartesianCoord(this.x, this.y, this.z);
		}
		
		public function copyTo(n:CartesianCoord):void
		{
			n.x = this.x;
			n.y = this.y;
			n.z = this.z;
		}
		
		public function copyFrom(n:CartesianCoord):void
		{
			this.x = n.x; 
			this.y = n.y; 
			this.z = n.z; 
		}
		
		public function reset(newx:Number = 0, newy:Number = 0, newz:Number = 0):void
		{
			this.x = newx; 
			this.y = newy; 
			this.z = newz; 
		}
		
		static public function get ZERO():CartesianCoord
		{
			return new CartesianCoord(0, 0, 0);
		}
	}
}

球坐標定義類SphericalCoord.cs

package hans_gis.coord
{
	public class SphericalCoord
	{
		public var radius:Number;
		public var theta:Number;
		public var phi:Number;
		
		static private var temp:SphericalCoord = SphericalCoord.ZERO;
		
		public function SphericalCoord(radius:Number=0, theta:Number=0, phi:Number=0)
		{
			this.radius = radius;
			this.theta = theta;
			this.phi = phi;
		}
		
		public function clone():SphericalCoord
		{
			return new SphericalCoord(this.radius, this.theta, this.phi);
		}
		
		public function copyTo(n:SphericalCoord):void
		{
			n.radius = this.radius;
			n.theta = this.theta;
			n.phi = this.phi;
		}
		
		public function copyFrom(n:SphericalCoord):void
		{
			this.radius = n.radius; 
			this.theta = n.theta; 
			this.phi = n.phi; 
		}
		
		public function reset(newradius:Number = 0, newtheta:Number = 0, newphi:Number = 0):void
		{
			this.radius = newradius; 
			this.theta = newtheta; 
			this.phi = newphi; 
		}
		
		static public function get ZERO():SphericalCoord
		{
			return new SphericalCoord(0, 0, 0);
		}
	}
}

坐標轉換定義類CoordsTransform.cs

package hans_gis.coord
{
	public class CoordsTransform
	{
		public function CoordsTransform()
		{
		}
		
		public function CartesianToSpherical(coord:CartesianCoord):SphericalCoord{
			var radius = this.GetModuloFromCartesianCoord(coord);
			var theta = this.GetThetaFromCartesianCoord(coord);
			var phi = this.GetPhiFromCartesianCoord(coord);
			return new SphericalCoord(radius, theta, phi);
		}
		
		protected function GetModuloFromCartesianCoord(coord:CartesianCoord):Number
		{
			return Math.sqrt( coord.x*coord.x + coord.y*coord.y + coord.z*coord.z );
		}
		
		protected function GetThetaFromCartesianCoord(coord:CartesianCoord):Number{
//			return Math.atan(Math.sqrt(coord.x*coord.x + coord.y*coord.y)/coord.z);
			return Math.acos(coord.z/this.GetModuloFromCartesianCoord(coord));
		}
		
		protected function GetPhiFromCartesianCoord(coord:CartesianCoord):Number{
			return Math.atan(coord.y/coord.x);
		}
		
		public function SphericalToCartesian(coord:SphericalCoord):CartesianCoord{
			var x = this.GetXFromSphericalCoord(coord);
			var y = this.GetYFromSphericalCoord(coord);
			var z = this.GetZFromSphericalCoord(coord);
			return new CartesianCoord(x, y, z);
		}
		
		protected function GetXFromSphericalCoord(coord:SphericalCoord):Number{
			return coord.radius*Math.sin(coord.theta)*Math.cos(coord.phi);
		}
		
		protected function GetYFromSphericalCoord(coord:SphericalCoord):Number{
			return coord.radius*Math.sin(coord.theta)*Math.sin(coord.phi);
		}
		
		protected function GetZFromSphericalCoord(coord:SphericalCoord):Number{
			return coord.radius*Math.cos(coord.theta);
		}
	}
}

實例運行結果

附:實例下載


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM