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. elasticsearch简介和倒排序索引介绍

    介绍 我们为什么要用搜索引擎?我们的所有数据在数据库里面都有,而且 Oracle.SQL Server 等数据库里也能提供查询检索或者聚类分析功能,直接通过数据库查询不就可以了吗?确实,我们大部分的查 ...

  2. 菜鸟译文(二)——使用Java泛型构造模板方法模式

    如果你发现你有很多重复的代码,你可能会考虑用模板方法消除容易出错的重复代码.这里有一个例子:下面的两个类,完成了几乎相同的功能: 实例化并初始化一个Reader来读取CSV文件: 读取每一行并解析: ...

  3. 【驱动】MTD子系统分析

    MTD介绍 MTD,Memory Technology Device即内存技术设备 字符设备和块设备的区别在于前者只能被顺序读写,后者可以随机访问:同时,两者读写数据的基本单元不同. 字符设备,以字节 ...

  4. mysql load本地文件失败,提示access denied

    mysql load本地文件失败,提示access denied 解决方式 直接谷歌到stackoverflow,解决方式如下 mysql -u myuser -p --local-infile so ...

  5. WebService 获取当前URL

    private string pageRoot = string.Empty; public virtual string PortalRoot { get { if (pageRoot == nul ...

  6. vmware的硬件选项里有关于虚拟化引擎的选项(虚拟机支持硬件虚拟化)

    前一阵子在使用陈沙克老师的博客安装devstack的时候就有一个疑问: 使用vmware创建虚拟机时,硬件选项里有关于虚拟化引擎的选项到底都代表了什么意思?  Intel VT-x/EPT和AMD-V ...

  7. tf.truncated_normal

    tf.truncated_normal truncated_normal( shape, mean=0.0, stddev=1.0, dtype=tf.float32, seed=None, name ...

  8. centos 配置subversion svn

    Subversion是一个自由,开源的版本控制系统. 1.安装: yum install subversion 2.配置 mkdir -p /var/svn/svnrepos #新建文件夹 svnad ...

  9. ios label 简单的长按复制文本信息

    在iOS开发过程中,有时候会用到UILabel展示的内容,那么就设计到点击UILabel复制它上面展示的内容的功能,也就是Label长按复制功能.网上有很多种给Label添加长按复制功能的方法,这里我 ...

  10. Android 程序drawable资源保存到data目录

    今天做了个小功能,就是把我们程序Drawable里面的图片保存到data目录下面,然后另外一个程序需要读取data目录里面保存的图片.涉及了data目录读写.这功能看上去挺简单,不过实际做的时候还是遇 ...