3

更新:スーパーフォーミュラを使用して描画する方法に関する回答は最後にあります

SuperEllipseを使用して、このような角の丸い四角形を描画する必要があります。 ここに画像の説明を入力

どこでも簡単にプロットできるときに描画する:

ここに画像の説明を入力

しかし、できないHLSLでは、プロットするかピクセルではないかという条件に行き詰まりました:

ここに画像の説明を入力

HLSL コードは次のとおりです。

sampler2D input : register(s0);

/// <summary>Explain the purpose of this variable.</summary>
/// <minValue>0.0</minValue>
/// <maxValue>10.0</maxValue>
/// <defaultValue>4.0</defaultValue>
float N : register(C1);

static const float pi = 3.1415926535f;

float2 superEllipse(float n, float a, float b, float theta)      
{
    float ct = cos(theta);
    float st = sin(theta);
    float x = a * sign(ct) * pow(abs(ct), 2.0f / n);
    float y = b * sign(st) * pow(abs(st), 2.0f / n);
    return float2(x, y);
}

float4 main(float2 uv : TEXCOORD) : COLOR 
{
    float2 uv1 = uv * float2(2.0f, 2.0f) - float2(1.0f, 1.0f);
    float angle = degrees(atan2(uv1.y, uv1.x)) + 180.0f;
    float tMax = pi * 2.0f;
    float theta = 1.0f / 360.0f * angle * tMax;
    float2 se = superEllipse(N, 1, 1, theta);
    float angle1 = degrees(atan2(se.y, se.x)) + 180.0f;
    float2 zero = float2(0.0f, 0.0f);
    float dist1 = distance(se, zero);
    float dist2 = distance(uv1, zero);

    float4 color = float4(0, 0, 0, 1);
    if(dist2 <= dist1)
        color += float4(0, 1, 0, 1);
    return color;

}

エラーは「dist1」および「dist2」変数にあるようです。

(シャザムで作成)

動作する C# コードは次のとおりです。

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
        }

        private void Run()
        {
            const double halfPi = Math.PI*2.0d;
            double nValue = trackBar1.Value/10.0d;
            double aValue = trackBar2.Value/100.0d;
            double bValue = trackBar3.Value/100.0d;
            label1.Text = nValue.ToString("F2");
            label2.Text = aValue.ToString("F2");
            label3.Text = bValue.ToString("F2");
            double n = nValue;
            double a = aValue;
            double b = bValue;

            // Build list of points
            const int points = 100;
            const double step = 360.0d/points;
            var list = new List<PointF>();
            for (int i = 0; i <= points; i++)
            {
                double angle = step*i;
                double t = 1.0d/360.0d*angle;
                double theta = t*halfPi;
                double x;
                double y;
                SuperEllipse.Evaluate(n, a, b, theta, out x, out y);
                list.Add(new PointF((float) x, (float) y));
            }

            /* Drawing */
            // Scale and center
            for (int index = 0; index < list.Count; index++)
            {
                PointF pointF = list[index];
                pointF.X++;
                pointF.Y++;
                pointF.X *= (pictureBox1.Width - 10)/2f;
                pointF.Y *= (pictureBox1.Height - 10)/2f;
                pointF.X += 5;
                pointF.Y += 5;
                list[index] = pointF;
            }
            // Draw and show
            var bitmap = new Bitmap(pictureBox1.Width, pictureBox1.Height);
            using (Graphics graphics = Graphics.FromImage(bitmap))
            {
                //graphics.TranslateTransform(1, 1);
                graphics.DrawLines(Pens.Red, list.ToArray());
                // graphics.FillClosedCurve(Brushes.Red, fs, FillMode.Alternate);
            }
            if (pictureBox1.Image != null)
            {
                pictureBox1.Image.Dispose();
            }
            pictureBox1.Image = bitmap;
        }

        private void trackBar1_Scroll(object sender, EventArgs e)
        {
            Run();
        }

        private void trackBar2_Scroll(object sender, EventArgs e)
        {
            Run();
        }

        private void trackBar3_Scroll(object sender, EventArgs e)
        {
            Run();
        }
    }

    public static class SuperEllipse
    {
        public static void Evaluate(double n, double a, double b, double theta, out double x, out double y)
        {
            double cost = Math.Cos(theta);
            double sint = Math.Sin(theta);
            x = a*Math.Sign(cost)*Math.Pow(Math.Abs(cost), 2.0d/n);
            y = b*Math.Sign(sint)*Math.Pow(Math.Abs(sint), 2.0d/n);
        }
    }
}

アップデート

HLSL の SuperFormula (まだ正しくない) ここに画像の説明を入力

sampler2D input : register(s0);

/// <summary>Explain the purpose of this variable.</summary>
/// <minValue>0.0</minValue>
/// <maxValue>8.0</maxValue>
/// <defaultValue>1.0</defaultValue>
float A : register(C0);

/// <summary>Explain the purpose of this variable.</summary>
/// <minValue>0.0</minValue>
/// <maxValue>8.0</maxValue>
/// <defaultValue>1.0</defaultValue>
float B : register(C1);

/// <summary>Explain the purpose of this variable.</summary>
/// <minValue>0.0</minValue>
/// <maxValue>8.0</maxValue>
/// <defaultValue>1.0</defaultValue>
float M : register(C2);

/// <summary>Explain the purpose of this variable.</summary>
/// <minValue>0.0, 0.0, 0.0</minValue>
/// <maxValue>8.0, 8.0, 8.0</maxValue>
/// <defaultValue>1.0, 1.0, 1.0</defaultValue>
float3 N : register(C3);

float4 main(float2 uv : TEXCOORD) : COLOR 
{
    float2 uv1 = uv * float2(2.0f, 2.0f) - float2(1.0f, 1.0f);
    float angle = degrees(atan2(uv1.y, uv1.x)) + 180.0f;
    float mt = M * angle / 4.0f;
    float magnitude = pow((pow((cos(mt) / A), N.y) + pow((sin(mt) / B), N.z)), -(1.0f / N.x));
    float2 zero = float2(0.0f, 0.0f);
    float dist1 = distance(uv1, zero);
    float4 color = float4(0, 0, 0, 1);
    if(dist1 <= magnitude)
        color += float4(dist1, 1, 0, 1);
    return color;
}

最後に、Kevin のおかげでSuperformulaを使用した角丸四角形:

ここに画像の説明を入力

sampler2D input : register(s0);

/// <summary>Explain the purpose of this variable.</summary>
/// <minValue>0.0</minValue>
/// <maxValue>8.0</maxValue>
/// <defaultValue>1.0</defaultValue>
float A : register(C0);

/// <summary>Explain the purpose of this variable.</summary>
/// <minValue>0.0</minValue>
/// <maxValue>8.0</maxValue>
/// <defaultValue>1.0</defaultValue>
float B : register(C1);

/// <summary>Explain the purpose of this variable.</summary>
/// <minValue>0.0</minValue>
/// <maxValue>8.0</maxValue>
/// <defaultValue>8.0</defaultValue>
float M : register(C2);

/// <summary>Explain the purpose of this variable.</summary>
/// <minValue>0.0, 0.0, 0.0</minValue>
/// <maxValue>8.0, 8.0, 8.0</maxValue>
/// <defaultValue>1.0, 1.0, 1.0</defaultValue>
float3 N : register(C3);

float4 main(float2 uv : TEXCOORD) : COLOR 
{
    float2 uv1 = uv * float2(2.0f, 2.0f) - float2(1.0f, 1.0f);
    float angle = atan2(uv1.y, uv1.x);
    float mt = M * angle / 4.0f;
    float magnitude = pow((pow((abs(cos(mt)) / A), N.y) + pow((abs(sin(mt)) / B), N.z)), -(1.0f / N.x));
    float2 zero = float2(0.0f, 0.0f);
    float dist1 = distance(uv1, zero);
    float4 color = float4(0, 0, 0, 1);
    float alpha = 1.0f / magnitude * dist1;
    if(dist1 <= magnitude)
        color += float4(1, 0.5, 0, 1);

    return color;
}
4

1 に答える 1

2

この問題はsuperEllipse(theta)、角度が であるとは限らないポイントを返すために発生しますtheta。たとえばsuperEllipse(3.6)、角度が 3.2 ラジアンのポイントを返します。結果として、あなたの関数では、とmain()の大きさを比較することはあまり意味がありません。角度が異なるからです。uv1se

この画像を参照してください。掃引する直線は に渡された角度を表しsuperEllipse、曲線の終点は新しい点が実際に配置される場所を表します。新しいポイントがスイープ ライン上にあることはめったにありません。

パラメトリック方程式ではなく、超楕円の極方程式を使用する場合は、それを使用して距離テストを実行できます。便利なことに、Wolfram Mathworldには次のような方程式があります。

ここに画像の説明を入力

それをコーディングして、メイン関数に入れるだけです。

float4 main(float2 uv : TEXCOORD) : COLOR 
{
    float2 uv1 = uv * float2(2.0f, 2.0f) - float2(1.0f, 1.0f);
    float angle = degrees(atan2(uv1.y, uv1.x)) + 180.0f;
    //to do: implement equation shown above. Use `angle` for theta.
    //`m` should be 4 if you want a four-pronged shape.
    float magnitude = ??? 

    float2 zero = float2(0.0f, 0.0f);
    float dist1 = distance(uv1, zero);
    float4 color = float4(0,0,0,1);
    if (dist1 <= magnitude) //uv is inside the superellipse
        color += float4(0,1,0,1);
    return color;
}
于 2012-09-10T16:29:15.837 に答える