2011-08-12 4 views
2

多角形の輪郭を表す点のパスがあります。パスはピクセルから構築されます。多くの点が接近している経路を最適化/簡略化しますか?

これは、すべてのポイントが互いに非常に近いことを意味しますが、すべてが一意であることを保証しています。

今、私は3点が同一線上にあるかどうかをチェックしていますが、そうであれば中間点を削除します。

ドットプロダクトを使用して同一直線上にあるかどうかを確認します。しかし、私のドットプロダクトの多くは0.0fです。何が間違っていますか?

void ImagePolygon::computeOptimized() 
{ 
    m_optimized = m_hull; 

    m_optimized.erase(
     std::unique(m_optimized.begin(), 
     m_optimized.end()), 
     m_optimized.end()); 

    int first = 0; 
    int second = 1; 

    std::vector<int> removeList; 

    for(int i = 2; i < m_optimized.size(); ++i) 
     { 
      second = i - 1; 
      first = i - 2; 

      if(isColinear(m_optimized[i - 2],m_optimized[i - 1],m_optimized[i])) 
      { 
       m_optimized.erase(m_optimized.begin() + i - 1); 
      removeList.push_back(i - 1); 
      } 
     } 

    std::sort(removeList.rbegin(),removeList.rend()); 
    for(int i = 0; i < removeList.size(); ++i) 
    { 
     m_optimized.erase(m_optimized.begin() + removeList[i]); 
    } 

} 

bool ImagePolygon::isColinear(const b2Vec2& a, const b2Vec2& b, const b2Vec2& c) const 
{ 
    b2Vec2 vec1 = b2Vec2(b.x - a.x, b.y - a.y); 
    vec1.Normalize(); 
    b2Vec2 vec2 = b2Vec2(c.x - b.x, c.y - b.y); 
    vec2.Normalize(); 

    float dotProduct = vec1.x * vec2.x + vec1.y * vec2.y; 

    //test value 
    return abs(dotProduct) > 0.00001f; 
} 

主要な問題は、私はそうので、私は、しきい値を設定していない事項はパスが同じくらいそれがあるべきように最適化されていないべきでないとき、私は0ドットの製品の多くを取得していますということです。

おかげ

float32 Normalize() 
{ 
    float32 length = Length(); 
    if (length < b2_epsilon) 
    { 
     return 0.0f; 
    } 
    float32 invLength = 1.0f/length; 
    x *= invLength; 
    y *= invLength; 

    return length; 
} 
+0

あなたはそれらがピクセルから構築されていると言いますが、それらはすべて整数座標ですか? (私は浮動小数点として格納されていると思うが、整数になる可能性はありますか?) – GManNickG

+0

b2Vec :: Normalize()とb2Vec2コンストラクタで少しのコードを表示できますか? – Kenji

+0

座標は整数ですが、後でそれらをメートルに変換して浮動小数点数に変換します。 b2vec2はfloatです。 – jmasterx

答えて

3

あなたが代わりに内積の2×2行列vec1.x * vec2.y - vec1.y * vec2.xをしたいです。点が同一直線上にある場合には行列式はゼロであり、点が直角を成すならば点積はゼロです。

0

この:

return abs(dotProduct) > 0.00001f; 

は、実際に彼らが平行であるかどうか、あなたのベクトルが垂直に(ではない)しているかどうかを語っています。パラレルの場合、0に近づくのではなく、1に近いかどうかを確認してください。

0

要素が削除された場合にインデックスをインクリメントしないでください。いくつかの値をスキップしています。以下を試してください:

for(int i = 2; i < m_optimized.size();) { 
    second = i - 1; 
    first = i - 2; 
    if (isColinear(m_optimized[i - 2],m_optimized[i - 1],m_optimized[i])) { 
     m_optimized.erase(m_optimized.begin() + i - 1); 
     removeList.push_back(i - 1); 
    } else i++; 
} 

また、私はremoveListの目的を理解できません。メインループ内のいくつかの点を消去し、補助ループ内の同じ点を消去しようとします。それはエラーのようです。ところで、それが構成された方法のためにremoveListを並べ替える理由はありません。

関連する問題