Skip to content

Commit 778cce7

Browse files
seto77claude
andcommitted
Add cursor-position axis/plane index readout in FormStereonet
- FindIndex(Vector3DBase) brute-forces the closest [UVW] and (HKL) within |U|+|V|+|W| ≤ 30 for the unit vector under the cursor - srcToSphere(PointD) factors the Wulff/Schmidt inverse projection and is shared by FindIndex and the tilt/azimuth readout - Fix tilt/azimuth display in Schmidt mode — the Wulff formula was applied unconditionally, giving wrong angles - Show Miller-Bravais 4-index (h k -h-k l) for the plane label on hex/trigonal crystals - Consolidate labelXpos/labelYpos into labelXYpos; add labelAxisPlane for [UVW] / (HKL) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 2b0926e commit 778cce7

9 files changed

Lines changed: 457 additions & 751 deletions

File tree

Crystallography.Controls/Crystallography.Controls.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
<TargetFramework>net10.0-windows</TargetFramework>
66
<UseWindowsForms>true</UseWindowsForms>
77
<UseWPF>true</UseWPF><!-- (260427Ch) LabelLaTeX で WpfMath の WPF 描画を使うため有効化 -->
8-
<AssemblyVersion>2026.5.17.0044</AssemblyVersion>
9-
<FileVersion>2026.5.17.0044</FileVersion>
8+
<AssemblyVersion>2026.5.17.0120</AssemblyVersion>
9+
<FileVersion>2026.5.17.0120</FileVersion>
1010
<ApplicationHighDpiMode>PerMonitorV2</ApplicationHighDpiMode>
1111
<ApplicationUseCompatibleTextRendering>true</ApplicationUseCompatibleTextRendering>
1212
<ApplicationVisualStyles>true</ApplicationVisualStyles>

Crystallography.OpenGL/Crystallography.OpenGL.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
<TargetFramework>net10.0-windows</TargetFramework>
66
<UseWindowsForms>true</UseWindowsForms>
77
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
8-
<AssemblyVersion>2026.5.17.0044</AssemblyVersion>
9-
<FileVersion>2026.5.17.0044</FileVersion>
8+
<AssemblyVersion>2026.5.17.0120</AssemblyVersion>
9+
<FileVersion>2026.5.17.0120</FileVersion>
1010
<!-- <SupportedOSPlatformVersion>7.0</SupportedOSPlatformVersion> --><!-- 260405Cl .NET 10はWindows7非対応のため削除 -->
1111
<Platforms>x64</Platforms>
1212
<!--

Crystallography/Crystallography.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
<OutputType>Library</OutputType>
55
<TargetFramework>net10.0-windows</TargetFramework>
66
<UseWindowsForms>true</UseWindowsForms>
7-
<AssemblyVersion>2026.5.17.0044</AssemblyVersion>
8-
<FileVersion>2026.5.17.0044</FileVersion>
7+
<AssemblyVersion>2026.5.17.0120</AssemblyVersion>
8+
<FileVersion>2026.5.17.0120</FileVersion>
99
<!-- <SupportedOSPlatformVersion>7.0</SupportedOSPlatformVersion> --><!-- 260405Cl .NET 10はWindows7非対応のため削除 -->
1010
<Platforms>x64</Platforms>
1111
<PublishReadyToRun>true</PublishReadyToRun>

ReciPro/FormStereonet.Designer.cs

Lines changed: 30 additions & 14 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ReciPro/FormStereonet.cs

Lines changed: 57 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -739,11 +739,23 @@ private void graphicsBox_MouseMove(object sender, System.Windows.Forms.MouseEven
739739
graphicsBox.Refresh();
740740
}
741741
// PointD pt = convertClientToSrc(e.X, e.Y); ; // (260322Ch) 旧実装: int overload helper を経由していた
742-
PointD pt = convertClientToSrc(new Point(e.X, e.Y)); ; // (260322Ch) その場で Point を作って直接変換する
743-
double azimuth = Math.Asin(2 * pt.Y / (1 + pt.X * pt.X + pt.Y * pt.Y));
744-
double tilt = (Math.Cos(azimuth) != 0) ? Math.Asin(2 * pt.X / (1 + pt.X * pt.X + pt.Y * pt.Y) / Math.Cos(azimuth)) : 0;
745-
labelYpos.Text = $"Tilt Y: {azimuth / Math.PI * 180:f3}°";
746-
labelXpos.Text = $"Tilt X: {tilt / Math.PI * 180:f3}°";
742+
var pt = convertClientToSrc(new Point(e.X, e.Y)); ; // (260322Ch) その場で Point を作って直接変換する
743+
// 260517Cl 旧実装 (Wulff 公式固定で Schmidt 時に誤値): srcToSphere() に置換
744+
// var azimuth = Math.Asin(2 * pt.Y / (1 + pt.X * pt.X + pt.Y * pt.Y));
745+
// var tilt = (Math.Cos(azimuth) != 0) ? Math.Asin(2 * pt.X / (1 + pt.X * pt.X + pt.Y * pt.Y) / Math.Cos(azimuth)) : 0;
746+
var vSphere = srcToSphere(pt);
747+
if (vSphere != null)
748+
{
749+
var azimuth = Asin(vSphere.Y);
750+
var tilt = Cos(azimuth) != 0 ? Asin(vSphere.X / Cos(azimuth)) : 0;
751+
labelXYpos.Text = $"{tilt / PI * 180:f3}° / {azimuth / PI * 180:f3}°";
752+
var (axis, plane) = FindIndex(vSphere);
753+
// 260517Cl Miller-Bravais 表示時 (hex/trigonal) は面指数を 4 指数 (h k -h-k l) に
754+
var planeStr = MillerBravaisActive
755+
? $"({plane.H}, {plane.K}, {-plane.H - plane.K}, {plane.L})"
756+
: $"({plane.H}, {plane.K}, {plane.L})";
757+
labelAxisPlane.Text = $"[{axis.U},{axis.V},{axis.W}] / {planeStr}";
758+
}
747759

748760
//真ん中ボタンが押されながらマウスが動いたとき
749761
if (e.Button == MouseButtons.Middle)
@@ -1549,6 +1561,46 @@ public void UpdatePlaneIndices()
15491561

15501562
private void radioButtonDelimiterNone_CheckedChanged(object sender, EventArgs e) => Draw();
15511563

1564+
/// <summary> ステレオネット上の点に対応する 3D 単位ベクトル (上半球) を返す。Schmidt 有効域外 (ρ²>2) は null。 </summary>
1565+
private Vector3DBase srcToSphere(PointD p) // 260517Cl 追加: 投影逆変換を MouseMove と FindIndex で共有
1566+
{
1567+
double X = p.X, Y = p.Y, rho2 = X * X + Y * Y;
1568+
if (radioButtonWulff.Checked) // Wulff (stereographic)
1569+
return new Vector3DBase(2 * X, 2 * Y, 1 - rho2) / (1 + rho2);
1570+
return rho2 > 2 ? null : new Vector3DBase(X * Sqrt(2 - rho2), Y * Sqrt(2 - rho2), 1 - rho2); // Schmidt (equal-area)
1571+
}
1572+
1573+
/// <summary> 3D 単位ベクトル vSphere (ラボ系・上半球) に最も近い晶帯軸/格子面の指数を返す。 </summary>
1574+
private ((int U, int V, int W) Axis, (int H, int K, int L) Plane) FindIndex(Vector3DBase vSphere) // 260517Cl 実装
1575+
{
1576+
//3つの指数の絶対値の合計が、以下の値になる範囲で、最も近い指数を探す。
1577+
int sumMax = 30;
1578+
1579+
if (formMain == null || formMain.Crystal == null || formMain.Crystal.A * formMain.Crystal.B * formMain.Crystal.C == 0)
1580+
return ((0, 0, 0), (0, 0, 0));
1581+
1582+
// 下半球モードは Z 反転 (DrawStereoNet と整合)。caller の vSphere を破壊しないよう新規生成
1583+
var v = radioButtonLowerSphere.Checked ? new Vector3DBase(vSphere.X, vSphere.Y, -vSphere.Z) : vSphere;
1584+
1585+
// R は直交回転行列なので R^T = R^-1。target を結晶 Cartesian 系に戻して loop 内の行列積を省く
1586+
var crystal = formMain.Crystal;
1587+
var target = crystal.RotationMatrix.Transpose() * v;
15521588

1589+
double bestScoreA = -2, bestScoreP = -2;
1590+
(int U, int V, int W) bestUvw = (0, 0, 0), bestHkl = (0, 0, 0);
1591+
for (int u = -sumMax, rem1 = sumMax - Abs(u); u <= sumMax; rem1 = sumMax - Abs(++u))
1592+
for (int vv = -rem1, rem2 = rem1 - Abs(vv); vv <= rem1; rem2 = rem1 - Abs(++vv))
1593+
for (int w = -rem2; w <= rem2; w++)
1594+
{
1595+
if ((u | vv | w) == 0 || Algebra.Irreducible(u, vv, w) != 1) continue;
1596+
var dirA = crystal.MatrixReal * (u, vv, w);
1597+
double cosA = dirA * target / dirA.Length;
1598+
if (cosA > bestScoreA) { bestScoreA = cosA; bestUvw = (u, vv, w); }
1599+
var dirP = crystal.MatrixInverseTransposed * (u, vv, w);
1600+
double cosP = dirP * target / dirP.Length;
1601+
if (cosP > bestScoreP) { bestScoreP = cosP; bestHkl = (u, vv, w); }
1602+
}
1603+
return (bestUvw, bestHkl);
1604+
}
15531605
}
15541606

0 commit comments

Comments
 (0)