|
少し長いですが確認用コードを作りました。
フォーム上にはPictureBox1つとキャップスタイル設定用にコンボボックスが2つあるイメージです。
private string[] CapStyleNames = { "キャップなし", "矢印1(大)", "矢印2(大)", "矢印3(中)", "矢印4(中)", "矢印5(小)", "矢印6(小)" };
private System.Windows.Forms.ColorDialog colorDialog = new ColorDialog();
private Bitmap moveBitMap = null;
private List<PointF> inputLinePointList = new List<PointF>();
private List<PointF[]> inputLinePointsList = new List<PointF[]>();
/// <summary>
/// 初期表示の線
/// </summary>
PointF[] initLines = new PointF[] {
new PointF(342.0f, 121.0f),
new PointF(334.0f, 120.0f),
new PointF(325.0f, 350.0f),
new PointF(331.0f, 353.0f),
};
public Form1()
{
InitializeComponent();
this.Init();
}
private void Init()
{
//始点キャップスタイルのコンボボックス設定
StartCapStyleCombo.DataSource = CapStyleNames.Clone() as string[];
StartCapStyleCombo.SelectedIndex = 1;
this.StartCapStyleCombo.SelectedIndexChanged += new System.EventHandler(this.StartCapStyleCombo_SelectedIndexChanged);
//終点キャップスタイルのコンボボックス設定
EndCapStyleCombo.DataSource = CapStyleNames.Clone() as string[];
EndCapStyleCombo.SelectedIndex = 1;
this.EndCapStyleCombo.SelectedIndexChanged += new System.EventHandler(this.EndCapStyleCombo_SelectedIndexChanged);
this.inputLinePointsList.Add(initLines);
this.DrawLineTest();
}
/// <summary>
/// 画面再描画
/// </summary>
private void DrawLineTest()
{
double scale = 1;
double transparency = (100.0 - (double)this.FillColorTransparency.Value) / 100.0;
Color color = Color.FromArgb(Convert.ToInt32(255 * transparency), this.FillColorPanel.BackColor);
double size = (double)this.SymbolSizeUpDown.Value;
string stCapName = Convert.ToString(this.StartCapStyleCombo.SelectedItem);
string enCapName = Convert.ToString(this.EndCapStyleCombo.SelectedItem);
using (Bitmap bitmap = new Bitmap(this.MapControl.Width, this.MapControl.Height))
using (Graphics graphics = Graphics.FromImage(bitmap))
{
graphics.SmoothingMode = SmoothingMode.AntiAlias;
float penSize = this.GetPixelSize(graphics, size);
using (Pen pen = new Pen(Color.FromArgb((int)(255 * 0.5), Color.Black), 2f))
{
pen.DashStyle = DashStyle.Dot;
PointF centerPt = new PointF();
int pointSize = 6;
foreach (PointF[] points in inputLinePointsList)
{
//矢印を付けないライン描画
graphics.DrawLines(pen, points);
//頂点の描画
foreach (PointF point in points)
{
centerPt.X = point.X - pointSize / 2f;
centerPt.Y = point.Y - pointSize / 2f;
graphics.FillEllipse(Brushes.Black, centerPt.X, centerPt.Y, pointSize, pointSize);
}
if (this.NomalDrawRbtButton.Checked)
{
//矢印を付けてライン描画
this.DrawLine_Normal(points, graphics, scale, color, penSize, stCapName, enCapName);
}
}
}
if (this.MapControl.Image != null)
{
this.MapControl.Image.Dispose();
}
this.MapControl.Image = bitmap.Clone() as Bitmap;
if (this.moveBitMap != null)
{
this.moveBitMap.Dispose();
}
this.moveBitMap = bitmap.Clone() as Bitmap;
}
}
/// <summary>
/// 標準描画
/// </summary>
/// <param name="points"></param>
/// <param name="graphics"></param>
/// <param name="scale"></param>
/// <param name="color"></param>
/// <param name="penSize"></param>
/// <param name="stCapName"></param>
/// <param name="enCapName"></param>
private void DrawLine_Normal(PointF[] points, Graphics graphics, double scale, Color color, float penSize, string stCapName, string enCapName)
{
if (points == null || points.Length < 2)
return;
bool isStArrowFill = false, isEndArrowFill = false;
float[] stwh = this.GetArrowSize(graphics, scale, penSize, stCapName, ref isStArrowFill);
float[] endwh = this.GetArrowSize(graphics, scale, penSize, enCapName, ref isEndArrowFill);
using (Pen pen = new Pen(color, penSize))
{
if (stwh != null)
{
pen.CustomStartCap = new AdjustableArrowCap(stwh[0], stwh[1], isStArrowFill);
}
if (endwh != null)
{
pen.CustomEndCap = new AdjustableArrowCap(endwh[0], endwh[1], isEndArrowFill);
}
graphics.DrawLines(pen, points);
}
}
/// <summary>
/// スタイルに合わせた矢印のサイズを取得します。
/// </summary>
/// <param name="graphics"></param>
/// <param name="scale"></param>
/// <param name="penSize"></param>
/// <param name="capName"></param>
/// <param name="retIsFill"></param>
/// <returns></returns>
private float[] GetArrowSize(Graphics graphics, double scale, float penSize, string capName, ref bool retIsFill)
{
switch (capName)
{
case "矢印2(大)":
case "矢印4(中)":
case "矢印6(小)":
retIsFill = false;
break;
case "矢印1(大)":
case "矢印3(中)":
case "矢印5(小)":
retIsFill = true;
break;
default:
return null;
}
// .netの仕様でキャップの塗りつぶしをしない場合、幅と高さを同じにした場合エラーが発生する
float fwidth = 0;
float fheight = 0;
// Terminateがついているものは端点に矢印を書く際に指定するサイズです。
switch (capName)
{
case "矢印1(大)":
case "矢印2(大)":
fwidth = 8.0F;
fheight = 10.0F;
break;
case "矢印3(中)":
case "矢印4(中)":
fwidth = 6.0F;
fheight = 7.5F;
break;
case "矢印5(小)":
case "矢印6(小)":
fwidth = 4.0F;
fheight = 5.0F;
break;
default:
return null;
}
fwidth *= (float)scale;
fheight *= (float)scale;
// 塗りつぶしの場合、線幅が2.0未満だと矢印の大きさが補正されてしまう。
// 調整のため70%の値にしている。
if (penSize < 2.0F && retIsFill)
{
fwidth *= 0.7F;
fheight *= 0.7F;
}
float[] floats = new float[2]; // 幅、高さ
floats[0] = fwidth;
floats[1] = fheight;
return floats;
}
/// <summary>
/// Point⇒Pixelへ変換
/// </summary>
/// <param name="graphics"></param>
/// <param name="pointSize"></param>
/// <returns></returns>
private float GetPixelSize(Graphics graphics, double pointSize)
{
float result = (float)(graphics.DpiX / 72.0 * pointSize);
return result;
}
private void StartCapStyleCombo_SelectedIndexChanged(object sender, EventArgs e)
{
this.DrawLineTest();
}
private void EndCapStyleCombo_SelectedIndexChanged(object sender, EventArgs e)
{
this.DrawLineTest();
}
|