2010/09/27(Mon) 14:35:24 編集(投稿者)
#VBの開発環境が手元になく、vbc.exeで手動コンパイルするのは面倒なのでC#でのコードですm(_ _)m
■No53787 (enough さん) に返信
> 調べていますと、下記のようなサイトを見つけましたが、gdiplus.dllのGraphicsPathではoutlineメソッド
> が存在し、パスの輪郭座標を取得する事ができる様で試してみたのですが、戻り値に座標配列を指定することが
> 出来ず断念致しました…。
> http://msdn.microsoft.com/ja-jp/library/dd296830.aspx
http://stackoverflow.com/questions/1592285/outline-a-path-with-gdi-in-net
のページにgdiplus.dllのOutlineの関数の呼び出し方法があったので試してみました。
以下のような図形に対しては上手く行きました。(立方体を下から見たような図形)
GraphicsPath path = new GraphicsPath();
path.AddPolygon(new PointF[] { new PointF(10F, 30F), new PointF(20F, 20F), new PointF(30F, 30F), new PointF(20F, 40F) });
path.AddPolygon(new PointF[] { new PointF(10F, 20F), new PointF(20F, 10F), new PointF(20F, 20F), new PointF(10F, 30F) });
path.AddPolygon(new PointF[] { new PointF(20F, 10F), new PointF(30F, 20F), new PointF(30F, 30F), new PointF(20F, 20F) });
ですが、同じ図形でもGraphicsPathの構築手順を変えるとうまく行きません。
例えば以下のコードは、上の図形のAddPolygonメソッド呼びだしの1行目と2行目を入れ替えただけですが。
一部の内部の線が消えません。
GraphicsPath path = new GraphicsPath();
path.AddPolygon(new PointF[] { new PointF(10F, 20F), new PointF(20F, 10F), new PointF(20F, 20F), new PointF(10F, 30F) });
path.AddPolygon(new PointF[] { new PointF(10F, 30F), new PointF(20F, 20F), new PointF(30F, 30F), new PointF(20F, 40F) });
path.AddPolygon(new PointF[] { new PointF(20F, 10F), new PointF(30F, 20F), new PointF(30F, 30F), new PointF(20F, 20F) });
上手く行く場合と行かない場合の理由がわからないので、このままでは実用には使えないですが、
何かの参考になればと思います。
-- 実験コード(C#:上手く行った例) --
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
using System.Runtime.InteropServices;
using System.Reflection;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
[DllImport(@"gdiplus.dll")]
public static extern int GdipWindingModeOutline(HandleRef path, IntPtr matrix, float flatness);
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
GraphicsPath path = new GraphicsPath();
path.AddPolygon(new PointF[] { new PointF(10F, 30F), new PointF(20F, 20F), new PointF(30F, 30F), new PointF(20F, 40F) });
path.AddPolygon(new PointF[] { new PointF(10F, 20F), new PointF(20F, 10F), new PointF(20F, 20F), new PointF(10F, 30F) });
path.AddPolygon(new PointF[] { new PointF(20F, 10F), new PointF(30F, 20F), new PointF(30F, 30F), new PointF(20F, 20F) });
this.BackgroundImage = new Bitmap(this.ClientSize.Width, this.ClientSize.Height);
Graphics g = Graphics.FromImage(this.BackgroundImage);
//元図形の確認用 (輪郭を見るときはコメントアウトしてください)
g.FillPath(Brushes.Blue, path);
g.DrawPath(Pens.Black, path);
HandleRef handle = new HandleRef(path, (IntPtr)path.GetType().GetField("nativePath", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(path));
GdipWindingModeOutline(handle, IntPtr.Zero, 0.25F);
//輪郭の確認用
g.DrawPath(Pens.Red, path);
//点の順番の確認用
int i = 0;
foreach (PointF p in path.PathPoints)
{
i++;
g.DrawString(i.ToString(), new Font(this.Font.FontFamily, 7), Brushes.Black, p);
}
}
}
}
---
※GdipWindingModeOutline関数の関数仕様のドキュメントを見つけられないため、
関数の使い方が正しいかどうかについてはわかりませんので、ご注意ください。