現在、私は線に沿って見えて見えない点を教えてくれる見通し線アルゴリズムを実装しています。だから、私が丘陵地帯の頂上に立っていると、私はどこに見えるか見えないかを知ることができます。3D Line-of-Sightアルゴリズム
点Aから点Bまでに生成される線には、AとBの間に均等に配置された点の数が含まれています。Aから始まり、仰角がAとBの間にあることがわかります。alphaAngle
。
次に、AとBの間の各点について、私はAとその点の間の仰角を得る。その点がこれまでの最高仰角(alphaAngleを除く)であれば、その点としてマークします。さもなければ、それは仰角が低く、そのため私はそれを見ることができず、その点をhasLOS = false
とマークするべきです。ここで
は、私が使用するいくつかのオブジェクト定義は、以下のとおりです。ここで
struct TerrainProfilPnt
{
double m_x_lon; //lon
double m_y_lat; //lat
double m_z_elev; //elev
bool m_hasLOS; //Does this point have line of sight from another point?
};
class TerrainProfilePartitioner; // Holds a collection of points that make up the line
は私のアルゴリズムが書き出されている、しかし、それは正しい結果を返しません。どちらかといえば、逃げてはいけないときに喪失していると主張しています(ある丘の後ろから別の丘の反対側に向かうように、私はそれを見ることができません)。 それは私が(山の下の谷の上の丘の上)すべき終点を見ることができないと主張する。だから、私は視線を見つけるのが間違っているのか、それともコードで間違って実装しているのか疑問に思います。
using Point = TerrainProfilePnt;
auto pointsInLine = terrainProfilePartitioner->GetPoints();
auto& pointsVec = pointsInLine->GetVector();
std::vector<Point> terrainProfileVec;
terrainProfileVec.reserve(pointsVec.size());
double start_xlon = 0.0f;
double start_ylat = 0.0f;
double start_zelev = 0.0f;
double end_xlon = 0.0f;
double end_ylat = 0.0f;
double end_zelev = 0.0f;
//The angle between the starting point and the ending point
double initialElevAngle = 0.0f;
//Assemble the first and last points
start_xlon = pointsVec.front().x();
start_ylat = pointsVec.front().y();
GetPointElevation(start_xlon, start_ylat, start_zelev);
end_xlon = pointsVec.back().x();
end_ylat = pointsVec.back().y();
GetPointElevation(end_xlon, end_ylat, end_zelev);
//Calculate the angle between the beginning and ending points
initialElevAngle = atan2(start_zelev, end_zelev) * 180/M_PI;
Point initialPoint;
initialPoint.m_x_lon = start_xlon;
initialPoint.m_y_lat = start_ylat;
initialPoint.m_z_elev = start_zelev;
initialPoint.m_hasLOS = true;
//pointsVec.push_back(initialPoint);
terrainProfileVec.push_back(initialPoint);
double oldAngle = 0.0f;;
bool hasOldAngle = false;
for (std::size_t i = 1; i < pointsVec.size(); ++i)
{
Point p;
p.m_x_lon = pointsVec.at(i).x();
p.m_y_lat = pointsVec.at(i).y();
GetPointElevation(p.m_x_lon, p.m_y_lat, p.m_z_elev);
double newAngle = atan2(start_zelev, p.m_z_elev) * 180/M_PI;
if (!hasOldAngle)
{
hasOldAngle = true;
oldAngle = newAngle;
p.m_hasLOS = true;
}
else
{
if (newAngle < oldAngle)
{
p.m_hasLOS = false;
}
else
{
oldAngle = newAngle;
p.m_hasLOS = true;
}
}
}
auto terrainPrfileSeq = new Common::ObjectRandomAccessSequence<TerrainProfilePnt>(terrainProfileVec);
return terrainPrfile