我在球体上有许多坐标(代表EEG-cap上的电极)。我的位置都是笛卡尔坐标和球坐标。
chan X Y Z long lat sph_radius
1 Fp1 8.08e+01 2.61e+01 -4.00 17.9 -2.70 85
2 Fp2 8.08e+01 -2.61e+01 -4.00 -17.9 -2.70 85
3 F3 5.76e+01 4.82e+01 39.90 39.9 28.00 85
4 F4 5.76e+01 -4.81e+01 39.90 -39.9 28.00 85
5 C3 3.87e-15 6.32e+01 56.90 90.0 42.00 85
6 C4 3.87e-15 -6.32e+01 56.90 -90.0 42.00 85
7 P3 -5.76e+01 4.82e+01 39.90 140.0 28.00 85
8 P4 -5.76e+01 -4.81e+01 39.90 -140.0 28.00 85
9 O1 -8.08e+01 2.61e+01 -4.00 162.0 -2.70 85
10 O2 -8.08e+01 -2.61e+01 -4.00 -162.0 -2.70 85
11 F7 4.99e+01 6.84e+01 -7.49 53.9 -5.06 85
12 F8 4.99e+01 -6.84e+01 -7.49 -53.9 -5.05 85
13 T3 5.18e-15 8.45e+01 -8.85 90.0 -5.97 85
14 T4 5.18e-15 -8.45e+01 -8.85 -90.0 -5.97 85
15 T5 -4.99e+01 6.84e+01 -7.49 126.0 -5.06 85
16 T6 -4.99e+01 -6.84e+01 -7.49 -126.0 -5.05 85
17 Fz 6.07e+01 0.00e+00 59.50 0.0 44.40 85
18 Cz 5.20e-15 0.00e+00 85.00 0.0 90.00 85
19 Pz -6.07e+01 -7.44e-15 59.50 -180.0 44.40 85
我想在z轴上逆时针/向下旋转所有电极90度,使得现在(长= 0,lat = 90)的电极Cz变为(long = 0,lat = 0)。我不关心旋转是在笛卡尔坐标还是球坐标上进行的,因为我可以轻松地将其转换为另一个。
我试图在这个网站上找到解决这个问题的方法,但它们都是压倒性的。如果有人能提供一个简单的R公式来完成这个轮换,我真的很感激。
答案 0 :(得分:1)
使用纬度/经度坐标(以data.table表示法)
# 1st we deal with cases where lat>0,
# i.e. rotation does not entail passing through the south pole
dt[, long.rot := long] # longitude stay in the same plane as we rotate
dt[, lat.rot := lat-90] # latitude moves south 90 degrees
# now we deal with case that were already in the southern hemisphere,
# which will rotate through the south pole and northwards on the opposite longitude
dt[lat < 0, long.rot := -sign(long)*(180-abs(long)) ]
dt[lat < 0, lat.rot := 180+lat.rot ]
然而,警告:在北极或靠近北极的点可能会出乎意料。严格来说,极点的经度是不确定的,应该作为NA给出。在这种情况下,旋转的经度将是NA,因为旋转的经度是点可能位于赤道上任何未指定的位置。
对于靠近极点的点,尽管经度在数学上有明确的定义,但该位置的小不确定性将被放大为赤道周围旋转点位置的大的不确定性
答案 1 :(得分:0)
您必须考虑到1度N / S与1度W / E不同,具体取决于纬度。
考虑赤道的1度W / E等于X,而在极点处的W / E等于0。因此,经度的1度等于X * Cos(纬度)。
这就是您要寻找的转变:
double x = pivot.lng; // Pivot coordinate
double y = pivot.lat; // Pivot coordinate
double cx = ((location.lng - pivot.lng) * 1852 * 60); // Horizontal distance in metres to pivot
double cy = ((location.lat - pivot.lat) * 1852 * 60 * Math.Cos(location.lat * Math.PI / 180); // Vertical distance in metres to pivot
double theta = -rotation * Math.PI / 180; // Angle, in radians
double x1 = cx * Math.Cos(theta) - cy * Math.Sin(theta); // Rotated cx
double y1 = cx * Math.Sin(theta) + cy * Math.Cos(theta); // Rotated cy
location.lat = y + (y1 / 1852 / 60); // Rotated latitude, from metres to degrees
location.lng = x + (x1 / 1852 / 60 / Math.Cos(y * Math.PI / 180)); // Rotated longitude, from metres to degrees
请稍等一下,因为如果从枢轴点到您要旋转的点的纬度距离太大,则会出现一些伪像。