3

.netのGraphicsPathを特定の形状にワープするための最良の方法を見つけようとしています。私が達成しようとしている結果は、テキストを上、下、扇形の左、右、および波のようなものにワープすることです。これらはすべて、エンベロープディストーション機能を使用してAdobeIllustratorで実現できます。

事前定義されたグリッドとポイントマッピングシステムを使用してポイントを変換する独自の方法を採用することを検討しました。ただし、これをすでに利用できるようにする方法については、いくつかのアルゴリズムまたはサンプルがあるようです。

4

2 に答える 2

4

少し前に作成したこの投稿をフォローアップしたいと思いました。私はこの投稿で最初にやりたかったことを達成するために他のいくつかの方法を考え出しました。まず、GraphicsPathには、それを実行する優れたwarp()メソッドがあり、任意のパスを長方形の4つのポイントにワープします。このアイデアを使用すると、以下でこれを達成できます。

右にワープアップ

これは、テキストがアーチ状になっているパスに適用された同じワープです

テキストアーチアップワープ

これは、warp()メソッドで長方形の4つのポイントを設定するだけで、古典的なスターウォーズのテキストワープです。 スターウォーズテキストワープ

アーチ型のパスに同じワープが適用されます。

スターウォーズワープでアーチ型

私が結論付けたのは、最初にアーチや波などのパスを入力してから、GraphicsPathにwarp()メソッドを適用することで、多くのワープを実現できるということです。

更新しました

私はついに、ほぼ2年後に、これに対する実際の解決策を実際に思いつくことになりました。ブログにコード付きの詳細な説明を投稿しました。 ここでそれを読む

于 2012-09-25T14:07:50.200 に答える
3

これが私たちが使用するキャプチャジェネレータからのいくつかの方法で、正しい方向にあなたを導くかもしれません:

    internal static void DrawPhrase(
        this Graphics graphics, 
        int width, 
        int height, 
        string phrase)
    {
        graphics.FillRectangle(
            Brushes.White,
            0,
            0,
            width,
            height);

        using (var gp = new GraphicsPath())
        {
            gp.AddString(phrase,
                         FontFamily.GenericMonospace,
                         (int)FontStyle.Bold,
                         33f,
                         new Point(0,
                                   0),
                         StringFormat.GenericTypographic);

            using (var gpp = gp.Deform(width, height))
            {
                var bounds = gpp.GetBounds();
                var matrix = new Matrix();
                var x = (width - bounds.Width) / 2 - bounds.Left;
                var y = (height - bounds.Height) / 2 - bounds.Top;
                matrix.Translate(x,
                                 y);
                gpp.Transform(matrix);
                graphics.FillPath(Brushes.Black,
                                  gpp);
            }
        }

        graphics.Flush();
    }
    internal static GraphicsPath Deform(
        this GraphicsPath path, 
        int width, 
        int height)
    {
        var WarpFactor = 4;
        var xAmp = WarpFactor * width / 300d;
        var yAmp = WarpFactor * height / 50d;
        var xFreq = 2d * Math.PI / width;
        var yFreq = 2d * Math.PI / height;
        var deformed = new PointF[path.PathPoints.Length];
        var xSeed = rng.NextDouble() * 2 * Math.PI;
        var ySeed = rng.NextDouble() * 2 * Math.PI;
        var i = 0;
        foreach (var original in path.PathPoints)
        {
            var val = xFreq * original.X + yFreq * original.Y;
            var xOffset = (int)(xAmp * Math.Sin(val + xSeed));
            var yOffset = (int)(yAmp * Math.Sin(val + ySeed));
            deformed[i++] = new PointF(original.X + xOffset,
                                     original.Y + yOffset);
        }

        return new GraphicsPath(deformed,
                                path.PathTypes);
    }
于 2012-01-26T14:18:37.053 に答える