public static class Spline
{
[System.Diagnostics.DebuggerDisplay("({X},{Y})")]
public partial struct Vec2
{
public float X, Y; public Vec2(float x, float y) { this.X = x; this.Y = y; } public static implicit operator PointF(Vec2 v) { return new PointF(v.X, v.Y); } public static implicit operator Vec2(PointF p) { return new Vec2(p.X, p.Y); } public static Vec2 operator +(Vec2 v1, Vec2 v2) { return new Vec2(v1.X + v2.X, v1.Y + v2.Y); } public static Vec2 operator -(Vec2 v1, Vec2 v2) { return new Vec2(v1.X - v2.X, v1.Y - v2.Y); } public static Vec2 operator *(Vec2 v, float f) { return new Vec2(v.X * f, v.Y * f); } public static Vec2 operator /(Vec2 v, float f) { return new Vec2(v.X / f, v.Y / f); } }
    
       /// <summary>
        /// '贝塞尔'内插。结果不包括头尾点
        /// </summary>
     public static PointF[] InterpolateBezier(PointF p0, PointF p1, PointF p2, PointF p3, int samples)
{
PointF[] result = new PointF[samples];
for (int i = ; i < samples; i++)
{
float t = (i + ) / (samples + 1.0f);
result[i] =
(Vec2)p0 * ( - t) * ( - t) * ( - t) +
(Vec2)p1 * ( * ( - t) * ( - t) * t) +
(Vec2)p2 * ( * ( - t) * t * t) +
(Vec2)p3 * (t * t * t);
}
return result;
} public static PointF[] InterpolateCardinalSpline(PointF p0, PointF p1, PointF p2, PointF p3, int samples)
{
const float tension = 0.5f;
Vec2 u = ((Vec2)p2 - (Vec2)p0) * (tension / ) + p1;
Vec2 v = ((Vec2)p1 - (Vec2)p3) * (tension / ) + p2;
return InterpolateBezier(p1, u, v, p2, samples);
}
    

      /// <summary>
      /// '基数样条'内插法。 points为通过点,samplesInSegment为两个样本点之间的内插数量。
      /// </summary>

public static PointF[] CardinalSpline(PointF[] points, int samplesInSegment)
{
List<PointF> result = new List<PointF>();
for (int i = ; i < points.Length - ; i++)
{
result.Add(points[i]);
result.AddRange(InterpolateCardinalSpline(
points[Math.Max(i - , )],
points[i],
points[i + ],
points[Math.Min(i + , points.Length - )],
samplesInSegment
));
}
result.Add(points[points.Length - ]);
return result.ToArray();
}
}

测试方法

public partial class Form1 : Form
{
protected override void OnPaint(PaintEventArgs e)
{
PointF[] ps = {new PointF(,), new PointF(, ), new PointF(, ), new PointF(,)};
// 系统的Graphics.DrawCurve,桃色
e.Graphics.DrawCurve(new Pen(Brushes.PeachPuff, ), ps);
// 自己取样,蓝色
e.Graphics.DrawLines(Pens.Blue, Spline.CardinalSpline(ps, ));
}
}

原文地址:https://blog.csdn.net/zheng558888/article/details/15816009

【转】Graphics.DrawCurve的算法的更多相关文章

  1. 戏说 .NET GDI+系列学习教程(二、Graphics类的方法)

    一.DrawBezier 画立体的贝尔塞曲线 private void frmGraphics_Paint(object sender, PaintEventArgs e) { Graphics g ...

  2. 从零开始学习GDI+ (二) 基本概念与基本操作

    从零开始学习GDI+ (一)我的第一个GDI+程序 上文给新手学习GDI+讲述了vs环境等的准备工作,并且可以直接用GDI+绘图了.本文开始,讲述的可能偏理论,建议学习的过程中大胆尝试,多使用API. ...

  3. [译]处理文本数据(scikit-learn 教程3)

    原文网址:http://scikit-learn.org/stable/tutorial/text_analytics/working_with_text_data.html 翻译:Tacey Won ...

  4. GDI+ 笔记

    1.GDI+模板 #include<windows.h> #include<GdiPlus.h> #include <time.h> #include <ma ...

  5. {Reship}{C#}{GDI+}GDI+画笔,线,区域类型

    =================================================================================== This article is ...

  6. Java实验三报告

    一.  实验内容 (一)敏捷开发与XP 摘要:一项实践在XP环境中成功使用的依据通过XP的法则呈现,包括:快速反馈.假设简单性.递增更改.提倡更改.优质工作.XP软件开发的基石是XP的活动,包括:编码 ...

  7. .Net验证码实现基础--Draw

    命名空间 using System.Draw; using System.Draw.Drawing2D; 在form等控件的 事件中 添加 paint事件 ///////画各种形状(空心)////// ...

  8. C#窗体程序画倾斜一定角度的椭圆

    using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using Sy ...

  9. GDI+: Curved Shapes

    原文 http://www.functionx.com/vcsharp2003/gdi/curves.htm Curves   Introduction to Curves   A curve is ...

随机推荐

  1. VLAN,GRE,VXLAN

    https://www.cnblogs.com/charles1ee/p/6629009.html VLAN介绍 局域网LAN(多个机器连接一个Hub或者Switch),是一个广播域 VLAN:一台S ...

  2. 如何理解java泛型类

    //泛型代码 public class Pair<T>{ private T first=null; private T second=null; public Pair(T fir,T  ...

  3. [Windows Azure] Guidelines for Connecting to Windows Azure SQL Database

    Guidelines for Connecting to Windows Azure SQL Database 6 out of 12 rated this helpful - Rate this t ...

  4. Java中的异常处理:何时抛出异常,何时捕获异常,何时处理异常?

    Java中的异常处理:何时抛出异常,何时捕获异常? 2017-06-07 1 异常分类 Throwable对象可以分为两组: 一组是unchecked异常,异常处理机制往往不用于这组异常,包括: Er ...

  5. Android开发(二)——自定义圆形控件的使用CircleImageView

    CircleImageView,a fast circular ImageView perfect for profile images. 主要的类CircleImageView: package d ...

  6. Oracle 安装报错 [INS-06101] IP address of localhost could not be determined 解决方法

    安装Oracle 11gR2,报错:[INS-06101] IP address of localhost could not be determined 出现这种错误是因为主机名和/etc/host ...

  7. js上传文件带参数,并且,返回给前台文件路径,解析上传的xml文件,存储到数据库中

    ajaxfileupload.js jQuery.extend({ createUploadIframe: function(id, uri) { //create frame var frameId ...

  8. 利用jQuery中live为动态生成Dom添加datepicker效果

    利用Live属性,focus时重新绑定控件 $(".datepickerDom").live("focus", function () { $(this).da ...

  9. git diff 的用法

    git diff 对比两个文件修改的记录 不带参数的调用 git diff filename 这种是比较 工作区和暂存区 比较暂存区与最新本地版本库 git diff --cached filenam ...

  10. oozie无法识别hadoopHA中的ns1

    [hadoop@dwdev-name1 m_goods_sale_detail]$ oozie job -config job.properties -run Error: E1603 : java. ...