公式如下
C#代碼如下
窗體代碼
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
HeartCurve hc = new HeartCurve();
public Form1()
{
InitializeComponent();
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
if (hc.path != null)
using (Pen pen = new Pen(Color.Red,2))
{
e.Graphics.DrawPath(pen,hc.path);
}
}
private void txtX_ValueChanged(object sender, EventArgs e)
{
hc.Create((double)txtB.Value,(double)txtZoom.Value, (int)txtOffsetX.Value, (int)txtOffsetY.Value);
Invalidate();
}
}
}
算法代碼
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
using System.Drawing.Drawing2D;
namespace WindowsFormsApplication1
{
public class HeartCurve
{
public GraphicsPath path = null;
public List<Point> data = new List<Point>();
/// <summary>
///
/// </summary>
/// <param name="b">變量</param>
/// <param name="zoom">放大倍數</param>
/// <param name="offsetX">x軸偏移量</param>
/// <param name="offsetY">y軸偏移量</param>
public void Create(double b, double zoom = 100, double offsetX = 300, double offsetY = 400)
{
try
{
if (data == null) data = new List<Point>();
data.Clear();
if (path != null) { path.Dispose(); path = null; }
if (path == null) path = new GraphicsPath();
double x0 = 0;
double y0 = 0;
double x1 = 0;
double start = -Math.Pow(3.3, 0.5);
double end = Math.Pow(3.3, 0.5);
for (double x = start; x < end; x += 0.001)
{
x0 = x * zoom + offsetX;
y0 = -(int)(Fx(x, b) * zoom) + offsetY;
if (y0 < -2048) continue;
if (y0 > 2048) continue;
if (x0 < -2048) continue;
if (x0 > 2048) continue;
Point pnt = new Point((int)x0, (int)y0);
if (data.Contains(pnt) == false)
data.Add(pnt);
}
Point pnt1 = new Point(0, 0);
Point pnt2 = new Point(0, 0);
for (int i = 0; i < data.Count; i++)
{
if (i > 0)
{
pnt2 = data[i];
path.AddLine(pnt1, pnt2);
pnt1 = pnt2;
}
else
{
pnt1 = data[i];
}
}
}
catch (Exception exp)
{
}
}
/// <summary>
/// 冪函數、三角函數與橢圓方程的神奇組合
/// </summary>
/// <param name="x"></param>
/// <param name="b"></param>
/// <returns></returns>
public double Fx(double x, double b)
{
return Math.Pow(Math.Abs(x), 2.0 / 3.0) + 0.9 * Math.Sqrt(3.3 - x * x) * Math.Sin(b * Math.PI * x);
}
}
}
效果如下