私は、ユーザーが岩の亀裂の画像をアップロードし、その亀裂にスプライン近似を適用できるようにするアプリケーションを開発しています。
その目的のためにQGraphicsView
、アップロードされた画像を表示します。画像がアップロードされると、ユーザーはにポイントを描画するオプションがありますscene
。これは、一貫して線で接続したいものです。それらの接続されたポイントは曲線を作ります、それは私がインタラクティブになりたいです。インタラクティブとは、ユーザーが曲線を壊さずにポイントをドラッグし、ポイントを接続する線をポイントとともに移動できるようにすることを意味します。また、ユーザーが選択したポイントを削除して、隣接するポイントが接続されたままになるようにしたいです。これらは私が望むすべての機能ではありませんが、私はあなたがアイデアを得ると思います。
私が行ったことは、1つの個別のポイントに関するすべての情報MeasurePoint
を継承しQGraphicsItem
、含むクラスを作成したことです。次のフィールドがあります。
int xPos;
int yPos;
int index;
bool movable;
bool selected;
そのクラスには、これらのポイントを管理するためのいくつかのメソッドもあります(フィールドのゲッター関数とセッター関数など)。ただし、接続機能は個々のポイントに関する情報のみが含まれ、それ以上は含まれないため、そのクラスには実装しません。ポイントをシーンに追加するだけのポイントの動作が気に入っています。しかし今、私は前に説明した方法でそれらを接続する必要があり、それを行う方法を本当に理解することはできません。
ポイントを保存するための最良の方法は何ですか?ポイント間の接続をどの程度正確に実装する必要がありますか?可能な限りの助けをいただければ幸いです。
MeasurePoint
この質問でクラスの実装が必要な場合は、編集します。
QGraphicsPathItemを使用してスプラインを描画します。次に、このQPainterPath::cubicTo
メソッドを使用して、ポイント間の接続を作成します。
2点間に滑らかなベジェ曲線を描くには、制御点を計算する必要があります。
二次ベジェ曲線に基づいたより優れたライブラリがたくさんありますが、以下の簡単な例では、Qtタイプと単純なアプローチを使用して、コントロールポイントを取得する方法を理解しています。
QPair<QPointF, QPointF> controlPoints(QPointF const& p0, QPointF const& p1, QPointF const& p2, qreal t=0.25)
{
QPair<QPointF, QPointF> pair;
qreal d01 = qSqrt( ( p1.x() - p0.x() ) * ( p1.x() - p0.x() ) + ( p1.y() - p0.y() ) * ( p1.y() - p0.y() ) );
qreal d12 = qSqrt( ( p2.x() - p1.x() ) * ( p2.x() - p1.x() ) + ( p2.y() - p1.y() ) * ( p2.y() - p1.y() ) );
qreal fa = t * d01 / ( d01 + d12 );
qreal fb = t * d12 / ( d01 + d12 );
qreal c1x = p1.x() - fa * ( p2.x() - p0.x() );
qreal c1y = p1.y() - fa * ( p2.y() - p0.y() );
qreal c2x = p1.x() + fb * ( p2.x() - p0.x() );
qreal c2y = p1.y() + fb * ( p2.y() - p0.y() );
pair.first = QPointF( c1x, c1y );
pair.second = QPointF( c2x, c2y );
return pair;
}
次に、ポイントリストを参照してQPainterPath
:を作成します。
QPainterPath BackgroundBuilder::buildPath(QList<QPointF> const& points)
{
QPainterPath pth;
QPair<QPointF, QPointF> pair = controlPoints(points.at(0), points.at(1), points.at(2));
QPointF p0 = pair.second;
pth.moveTo(0, 0);
pth.lineTo(p0);
for (int i = 2; i != points.count() - 1; ++i)
{
QPair<QPointF, QPointF> pair = controlPoints( points.at(i - 1), points.at(i), points.at(i + 1));
pth.cubicTo( p0, pair.first, points.at( i ) );
p0 = pair.second;
}
return pth;
}
このコードを汎用的に保つには、MeasurePoint
をに変換する必要がある場合がありますQPointF
。
QList<QPointF> points;
QList<MeasurePoint*> measures = ...;
for (MeasurePoint* measure: measures)
{
points << QPointF(measure.xPos, measure.yPos);
}
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加