18

メソッドを使用してクワッド カーブ パスを作成しましたCGPathAddQuadCurveToPoint。パスを完璧に取得しました。しかし、パスに参加しているすべての座標点を知りたいです。

パス内のすべての座標点を取得する方法はありますか?

そうでない場合、曲線内のすべてのポイントを数学的に取得するための他の解決策はありません。

前もってありがとう、Vamshi

4

6 に答える 6

14

これは、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

于 2012-07-27T03:22:31.353 に答える
2

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();
于 2013-12-18T05:21:03.443 に答える
1

パスの moveto、lineto、curveto 要素で作業する場合は、CGPathApply を使用します。これをプログラム内の関数へのポインターに渡すと、パスの要素ごとにその関数が 1 回呼び出されます。

残念ながら、AppKit のNSBezierPathのように各要素を要求する方法はありません。関数は唯一の方法です。

パスと交差するすべてのピクセルを特定したい場合は、残念なことに、それは実用的ではありません。なぜその情報が必要なのか、私には思いつきません。PDF contextsなどの一部のコンテキストには、ピクセルさえありません。そのような場合、ピクセルに関係する質問は、非 sequitur です。

于 2009-05-08T19:15:37.957 に答える
0

二次曲線はまさにそれです -- 曲線です。無限に多くの点があり、単純な線分ではないため、すべての点のリストを取得することは不可能です。

オブジェクトのクエリに使用できる関数のリストについては、Quartz パスに関する情報の取得を参照してください。CGPath残念ながら、取得しようとしている最も有用な情報CGPathContainsPoint()は、パスの領域内に特定のポイントが含まれているかどうかのみを通知する を使用することのようです。

于 2009-05-08T18:19:51.977 に答える
0

そうでない場合、曲線内のすべてのポイントを数学的に取得するための他の解決策はありません。

それらは何のために必要ですか、つまり、どのような問題を解決しようとしていますか? 2 つの曲線を交差させる場合は、これを数学的に行うことができます。2 つの曲線方程式を互いに等しく設定し、未知数を解くだけです。

于 2009-05-08T19:58:16.310 に答える
0

Java2D FlatteningPathIterator クラスと同等のものを求めていると思います。たとえばpath.getPathIterator(null, 1.0)、元のパスにcurveToとquadToがあったとしても、Java2Dは「lineTo」セグメントのみの反復子を返します.double引数は「平坦性」を制御し、曲線上の任意の点を簡単に計算できるようにします. Cocoa で同じものを探していますが、何も見つかりませんでした。解決策を見つけたら、私に知らせてください。移植できる曲線の実装 (例: http://sourceforge.net/projects/curves/ ) がありますが、Cocoa と同じアルゴリズムを使用しないと、補間の間にエラーが発生する可能性があるというリスクが常にあります。およびストロークされた NSBezierPath/CGPath。

于 2009-06-12T07:05:39.447 に答える