メソッドを使用してクワッド カーブ パスを作成しましたCGPathAddQuadCurveToPoint
。パスを完璧に取得しました。しかし、パスに参加しているすべての座標点を知りたいです。
パス内のすべての座標点を取得する方法はありますか?
そうでない場合、曲線内のすべてのポイントを数学的に取得するための他の解決策はありません。
前もってありがとう、Vamshi
メソッドを使用してクワッド カーブ パスを作成しましたCGPathAddQuadCurveToPoint
。パスを完璧に取得しました。しかし、パスに参加しているすべての座標点を知りたいです。
パス内のすべての座標点を取得する方法はありますか?
そうでない場合、曲線内のすべてのポイントを数学的に取得するための他の解決策はありません。
前もってありがとう、Vamshi
これは、3 次ベジエ曲線用の wykobi C++ ライブラリ ルーチンを使用して行うことができます。Wykobi のライブラリは、2 次ベジエ曲線もサポートしています。
もちろん、誰かが指摘したように、すべてのポイントが必要なわけではありません(不可能ではありませんが、無限の時間がかかります:)。Wykobi を使用すると、特定の数のポイントを簡単に取得できます。開始点、c1、c2、および終了点 (c1、c2 は制御点) が CGContextAddCurveToPoint に指定されたものとまったく同じである場合、点は完全に配置されます。コア グラフィックスによって描かれた線に沿って - パス上のいくつかのポイントでパターンを描くなどの操作を実行できます。
参照: http://www.codeproject.com/Articles/22568/Computational-Geometry-C-and-Wykobi
また、wykobi を使い始めた後、Boost の一部である同様の、おそらくさらに優れたライブラリがあると聞きましたが、まだチェックしていません。
wykobi ポイントと CGPoints の間のブリッジとして C++ クラス WPoint を作成しました (C++ 楽しいです!)。以下にいくつかのコードを示します (WPoint はありませんが、CGPoint とまったく同じレイアウトであることが想像できるので、適切なキャストを行えば簡単に変換できます。
NSMutableArray* result = [[NSMutableArray alloc] init];
wykobi::cubic_bezier<CGFloat,2> bezier;
bezier[0] = (WPoint)p1; // start point, in CG we did a CGMoveToPoint
bezier[1] = (WPoint)b1i; // control 1
bezier[2] = (WPoint)b2i; // control 2
bezier[3] = (WPoint)p2; // end point
std::vector<WPoint> point_list;
int numPoints = p2.dist(p3) * pointDensity;
// *** here's the magic ***
wykobi::generate_bezier(bezier,std::back_inserter(point_list), numPoints);
for (int i=0; i<numPoints; i++) {
CGPoint p = (CGPoint)(point_list[i]);
[result addObject:[NSValue valueWithCGPoint:p]];
}
// result has your points!
Boost ジオメトリ ライブラリへのリンクは次のとおりです: http://www.boost.org/doc/libs/1_47_0/libs/geometry/doc/html/geometry/introduction.html
CGContextSetLineDash を使用する
この関数の目的は破線を作成することですが、それを使用してより小さなセグメントを取得できます。各セグメントの始点は点として扱うことができます。
CGSize bbSize = CGPathGetBoundingBox(path).size;
UIGraphicsBeginImageContext(bbSize);
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(ctx, 1.0);
CGContextAddPath(ctx, path);
CGContextSetLineDash(ctx, phase, lengths, count);
CGContextReplacePathWithStrokedPath(ctx);
result = CGContextCopyPath(ctx);
UIGraphicsEndImageContext();
パスの moveto、lineto、curveto 要素で作業する場合は、CGPathApply を使用します。これをプログラム内の関数へのポインターに渡すと、パスの要素ごとにその関数が 1 回呼び出されます。
残念ながら、AppKit のNSBezierPathのように各要素を要求する方法はありません。関数は唯一の方法です。
パスと交差するすべてのピクセルを特定したい場合は、残念なことに、それは実用的ではありません。なぜその情報が必要なのか、私には思いつきません。PDF contextsなどの一部のコンテキストには、ピクセルさえありません。そのような場合、ピクセルに関係する質問は、非 sequitur です。
二次曲線はまさにそれです -- 曲線です。無限に多くの点があり、単純な線分ではないため、すべての点のリストを取得することは不可能です。
オブジェクトのクエリに使用できる関数のリストについては、Quartz パスに関する情報の取得を参照してください。CGPath
残念ながら、取得しようとしている最も有用な情報CGPathContainsPoint()
は、パスの領域内に特定のポイントが含まれているかどうかのみを通知する を使用することのようです。
そうでない場合、曲線内のすべてのポイントを数学的に取得するための他の解決策はありません。
それらは何のために必要ですか、つまり、どのような問題を解決しようとしていますか? 2 つの曲線を交差させる場合は、これを数学的に行うことができます。2 つの曲線方程式を互いに等しく設定し、未知数を解くだけです。
Java2D FlatteningPathIterator クラスと同等のものを求めていると思います。たとえばpath.getPathIterator(null, 1.0)
、元のパスにcurveToとquadToがあったとしても、Java2Dは「lineTo」セグメントのみの反復子を返します.double引数は「平坦性」を制御し、曲線上の任意の点を簡単に計算できるようにします. Cocoa で同じものを探していますが、何も見つかりませんでした。解決策を見つけたら、私に知らせてください。移植できる曲線の実装 (例: http://sourceforge.net/projects/curves/ ) がありますが、Cocoa と同じアルゴリズムを使用しないと、補間の間にエラーが発生する可能性があるというリスクが常にあります。およびストロークされた NSBezierPath/CGPath。