来自于《编程珠玑》
计算球面的距离,输入是球面上点的经度和纬度,得到一个原始点集,再得到另一个测量点集,输出测量点集中的每个点到原始点集中的每个点的距离,这里的距离是两个点的集合距离,即使在笛卡尔坐标系中的欧氏距离,根据经度和纬度,转换为点在笛卡尔积中的 x, y, z 坐标
测试数据:
5
E23 N35
E150 N80
W50 N20
W175 N55
E20 S35
3
E105 S70
W40 S50
W160 S85
1 //
2 // goonyangxiaofang(at)163(dot)com
3 // QQ: 五九一二四七八七六
4 //
5
6 #include <iostream>
7 #include <string>
8 #include <vector>
9 #include <cmath>
10
11 class PointSet
12 {
13 public:
14 struct Point
15 {
16 std::string longitude;
17 std::string latitude;
18 double longi;
19 double lati;
20 double x, y, z;
21 private:
22 void ajust()
23 {
24 if (longitude[0] == 'E')
25 {
26 longi = atof(longitude.c_str() + 1);
27 }
28 else if (longitude[0] == 'W')
29 {
30 longi = 360.0 - atof(longitude.c_str() + 1);
31 }
32 if (latitude[0] == 'N')
33 {
34 lati = atof(latitude.c_str() + 1);
35 }
36 else if (latitude[0] == 'S')
37 {
38 lati = -atof(latitude.c_str() + 1);
39 }
40 x = R * cos(lati * PI / 180.0) * cos(longi * PI / 180.0);
41 y = R * cos(lati * PI / 180.0) * sin(longi * PI / 180.0);
42 z = R * sin(lati * PI / 180.0);
43 }
44 public:
45 Point() : longitude(""), latitude(""), longi(0.0), lati(0.0), x(0.0), y(0.0), z(0.0) {}
46 Point(const std::string& s1, const std::string& s2) : longitude(s1), latitude(s2)
47 {
48 ajust();
49 }
50 Point(const Point& p) : longitude(p.longitude), latitude(p.latitude), longi(p.longi), lati(p.lati), x(p.x), y(p.y), z(p.z) {};
51 Point& operator=(const Point& p)
52 {
53 longitude = p.longitude;
54 latitude = p.latitude;
55 longi = p.longi;
56 lati = p.lati;
57 x = p.x;
58 y = p.y;
59 z = p.z;
60 return *this;
61 }
62 bool operator==(const Point& p) const
63 {
64 return longitude == p.longitude && latitude == p.latitude;
65 }
66 double distance(const Point& p)
67 {
68 return sqrt((x - p.x) * (x - p.x) + (y - p.y) * (y - p.y) + (z - p.z) * (z - p.z));
69 }
70 friend std::istream& operator>>(std::istream& in, Point& p);
71 friend std::ostream& operator<<(std::ostream& out, const Point& p);
72 };
73 private:
74 std::vector<Point> m_set;
75 static const double R;
76 static const double PI;
77 public:
78 void insert(const std::string& s1, const std::string& s2)
79 {
80 Point p(s1, s2);
81 m_set.push_back(p);
82 }
83 void insert(const Point& p)
84 {
85 m_set.push_back(p);
86 }
87 void print()
88 {
89 for (std::size_t i = 0; i < m_set.size(); ++i)
90 {
91 std::cout << "Point " << i + 1 << ": ";
92 std::cout << m_set[i];
93 }
94 }
95 std::size_t size()
96 {
97 return m_set.size();
98 }
99 Point& operator[](std::size_t i)
100 {
101 return m_set[i];
102 }
103 const Point& operator[](std::size_t i) const
104 {
105 return m_set[i];
106 }
107 };
108
109 std::istream& operator>>(std::istream& in, PointSet::Point& p)
110 {
111 std::string s1, s2;
112 in >> s1 >> s2;
113 PointSet::Point p2(s1, s2);
114 p = p2;
115 return in;
116 }
117
118 std::ostream& operator<<(std::ostream& out, const PointSet::Point& p)
119 {
120 out << p.longitude << ' ';
121 out << p.latitude << ' ';
122 out << p.longi << ' ';
123 out << p.lati << ' ';
124 out << p.x << ' ';
125 out << p.y << ' ';
126 out << p.z << ' ';
127 out << std::endl;
128 return out;
129 }
130
131 const double PointSet::R = 6400.0;
132 const double PointSet::PI = 3.1415926;
133
134 int main()
135 {
136 PointSet ps;
137 PointSet::Point p;
138 long n;
139 std::cin >> n;
140 for (long i = 0; i < n; ++i)
141 {
142 std::cin >> p;
143 ps.insert(p);
144 }
145 ps.print();
146
147 PointSet measure_ps;
148 std::cin >> n;
149 for (long i = 0; i < n; ++i)
150 {
151 std::cin >> p;
152 measure_ps.insert(p);
153 }
154 measure_ps.print();
155 for (std::size_t i = 0; i < measure_ps.size(); ++i)
156 {
157 for (std::size_t j = 0; j < ps.size(); ++j)
158 {
159 std::cout << "From " << i + 1 << " to " << j + 1 << ": " << ps[j].distance(measure_ps[i]) << std::endl;
160 }
161 }
162 return 0;
163 }
164
posted on 2011-03-08 14:07
unixfy 阅读(209)
评论(0) 编辑 收藏 引用