「もう一つの」極座標変換

(x,\quad y)平面上の関数を極座標(r,\quad \theta)積分すると便利なことがある。少々トリッキーだが有名な例は
I:= \int_{{\mathbf{R}}}^{} e ^{-x ^{2} } dx
の例で、この場合には
I ^{2} = \int_{{\mathbf{R}}}^{}  \int_{{\mathbf{R}}}^{} e ^{-x ^{2} } e ^{-y ^{2} } dxdy

r=cos\theta,\quad y=r\sin\theta \quad(0 \le r < \infty,\:0\le\theta<2\pi)
と変換してやると
dx=\cos\theta dr - r\sin\theta d\theta,\quad dy=\sin\theta dr + r \cos\theta d\theta
より
dx\wedge dy = r\cos^2\theta dr\wedge d\theta - r \sin^2\theta d\theta\wedge dr = r dr\wedge d\theta
なので
I^2=\int_{0}^{\infty}\quad\int_{0}^{2\pi}e^{-r^{2}}drd\theta \quad =\quad \int_0^{2\pi}d\theta \quad\int_0^{\infty}re^{-r^2}dr \quad =\quad 2\pi \quad\frac{\quad 1\quad}{2}\quad[e^{-r^2}]_{0}^{\infty}= \pi.
I被積分関数は正値をとるのでI\ge 0だからI=\sqrt{\pi}が得られる。


さて、上では\quad r\quad\quad 0\le r < \infty\quad の範囲で動かしたが、[tex:\quad -\infty

TabControl のタブをドラッグアンドドロップで入れ替えできるようにする

自分で作っているC#アプリケーションでタブを移動させたくなったが、標準のタブコントロールでは
タブを移動させることが出来ない。そこで

http://watcher.moe-nifty.com/memo/2009/02/ctabcontrol-b32.html

のソースを改変して作ってみた。


//タブをドラッグで移動できるようにしたクラス。
class TabControlEx : TabControl
{
private int mouseDownPointX = 0;
private int mouseDownPointY = 0;
private Rectangle dragBoxFromMouseDown = Rectangle.Empty;

public TabControlEx()
{
AllowDrop = true;
ClearDragTarget();
}

protected override void OnDragOver(System.Windows.Forms.DragEventArgs e)
{
base.OnDragOver(e);

//■イベントが起きた位置をクライアント座標ポイントptに変換する.
Point pt = PointToClient(new Point(e.X, e.Y));

//■ptからhovering overタブを得る.
TabPage hoverTab = GetTabPageByTab(pt);

//■タブがキチンと取れているかどうかで条件分岐
if (hoverTab != null && e.Data.GetDataPresent(typeof(TabPage)))
{
//タブが取得できた場合の処理
e.Effect = DragDropEffects.Move;
TabPage draggedTab = (TabPage)e.Data.GetData(typeof(TabPage));

int srcTabIndex = FindIndex(draggedTab);
int dstTabIndex = FindIndex(hoverTab);

if (srcTabIndex != dstTabIndex)
{
this.SuspendLayout();//★これ大事
TabPage tmp = TabPages[srcTabIndex];
TabPages[srcTabIndex] = TabPages[dstTabIndex];
TabPages[dstTabIndex] = tmp;

SelectedTab = draggedTab;

this.ResumeLayout();//★これも大事
}
}
else
{
//タブが取得できなかった場合の処理
e.Effect = DragDropEffects.None;//何もしなくて良い
}
}

protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);

if (dragBoxFromMouseDown != Rectangle.Empty
&&
!dragBoxFromMouseDown.Contains(e.X, e.Y))
{
if (this.TabCount <= 1)
{
return;
}

Point pt = new Point(mouseDownPointX, mouseDownPointY);
TabPage tp = GetTabPageByTab(pt);

if (tp != null)
{
DoDragDrop(tp, DragDropEffects.All);
}
}
}

protected override void OnMouseUp(MouseEventArgs e)
{
base.OnMouseUp(e);
ClearDragTarget();
}

protected override void OnMouseLeave(EventArgs e)
{
base.OnMouseLeave(e);
ClearDragTarget();
}

private void ClearDragTarget()
{
dragBoxFromMouseDown = Rectangle.Empty;
mouseDownPointX = 0;
mouseDownPointY = 0;
}

private void SetupDragTarget(int x, int y)
{
Size dragSize = SystemInformation.DragSize;

dragBoxFromMouseDown =
new Rectangle(new Point(x - (dragSize.Width / 2),
y - (dragSize.Height / 2)), dragSize);
mouseDownPointX = x;
mouseDownPointY = y;
}

protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
ClearDragTarget();

if (e.Button != MouseButtons.Left
||
e.Clicks >= 2)
return;

SetupDragTarget(e.X, e.Y);
}

//■GetTabPageByTab : Point --> TabPage + {null}
private TabPage GetTabPageByTab(Point pt)
{
for (int i = 0; i < TabPages.Count; i++)
{
if (GetTabRect(i).Contains(pt))
{
return TabPages[i];
}
}

return null;
}

//■FindIndex: TabPage --> Int + { null }
private int FindIndex(TabPage page)
{
for (int i = 0; i < TabPages.Count; i++)
{
if (TabPages[i] == page)
{
return i;
}
}
return -1;
}
}