Skip to content

Instantly share code, notes, and snippets.

@jyoshida-sci
Last active January 29, 2017 13:55
Show Gist options
  • Save jyoshida-sci/1742c27ed6474d23e5da1e31d96b6382 to your computer and use it in GitHub Desktop.
Save jyoshida-sci/1742c27ed6474d23e5da1e31d96b6382 to your computer and use it in GitHub Desktop.
Coordinate transformation for tracking

#CoordinateTransformation and SystemParameters

##header2-1

aaaa

aaaa

##header2-1

aaa ##header2-1

rrrr

{
"Time": "2016/09/02 10:00:00",
"MarkMeass": [
{ "befdevx":0.0010, "befdevy":-0.0020, "stagex":0.00301020, "stagey":-0.00501940, "Time": "2016/09/01 10:01:00" },
{ "befdevx":150.0020, "befdevy":150.0090, "stagex":150.99400480, "stagey":151.55108990, "Time": "2016/09/01 10:02:00" },
{ "befdevx":-149.9960, "befdevy":150.0150, "stagex":-151.34398680, "stagey":151.43715010, "Time": "2016/09/01 10:03:00" },
{ "befdevx":-150.0200, "befdevy":-149.9870, "stagex":-151.00817160, "stagey":-151.53487930, "Time": "2016/09/01 10:04:00" },
{ "befdevx":150.0120, "befdevy":-150.0000, "stagex":151.36409360, "stagey":-151.42799520, "Time": "2016/09/01 10:05:00" }
]
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MathNet.Numerics;
using MathNet.Numerics.LinearAlgebra;
namespace NagaraStage {
/// <summary>
/// アフィン変換行列を定義します.
/// a, b, p
/// c, d, q
/// </summary>
public class Affine
{
private double a, b, c, d, p, q;
public double A { get { return a; } set { a = value; } }
public double B { get { return b; } set { b = value; } }
public double C { get { return c; } set { c = value; } }
public double D { get { return d; } set { d = value; } }
public double P { get { return p; } set { p = value; } }
public double Q { get { return q; } set { q = value; } }
List<Vector2> srcs;
List<Vector2> dsts;
public Affine()
{
this.a = 1.0;
this.b = 0.0;
this.c = 0.0;
this.d = 1.0;
this.p = 0.0;
this.q = 0.0;
srcs = new List<Vector2>();
dsts = new List<Vector2>();
}
public Affine(double _a, double _b, double _c, double _d, double _p, double _q)
{
this.a = _a;
this.b = _b;
this.c = _c;
this.d = _d;
this.p = _p;
this.q = _q;
srcs = new List<Vector2>();
dsts = new List<Vector2>();
}
public Affine(Affine orig) {
a = orig.A;
b = orig.B;
c = orig.C;
d = orig.D;
p = orig.P;
q = orig.Q;
srcs = orig.srcs;
dsts = orig.dsts;
}
public static bool operator== (Affine y ,Affine z) {
return (y.a == z.a && y.b == z.b && y.c == z.c && y.d == z.d && y.p == z.p && y.q == z.q);
}
public static bool operator !=(Affine y, Affine z)
{
return (y.a != z.a || y.b != z.b || y.c != z.c || y.d != z.d || y.p != z.p || y.q != z.q);
}
/// <summary>
/// 与えられた座標点をアフィンパラメータを使って変換します.
/// </summary>
/// <param name="src">元の座標点</param>
/// <returns>変換後の座標点</returns>
public Vector2 Trans(Vector2 src) {
Vector2 dst = new Vector2();
dst.X = A * src.X + B * src.Y + P;
dst.Y = C * src.X + D * src.Y + Q;
return dst;
}
public Vector2 Trans(double x, double y) {
return Trans(new Vector2(x, y));
}
/// <summary>
/// 平行移動無し回転のみの変換
/// </summary>
/// <param name="src">元の座標点</param>
/// <returns>変換後の座標点</returns>
public Vector2 TransRot(Vector2 src)
{
Vector2 dst = new Vector2();
dst.X = A * src.X + B * src.Y;
dst.Y = C * src.X + D * src.Y;
return dst;
}
public Vector2 TransRot(double x, double y)
{
return TransRot(new Vector2(x, y));
}
/// <summary>
/// 逆アフィン変換パラメータを取得します.
/// </summary>
public Affine Inverse {
get {
Affine inv = new Affine();
double det = A * D - B * C;
if (det == 0.0) {
return inv;
} else {
inv.A = D / det;
inv.B = -B / det;
inv.C = -C / det;
inv.D = A / det;
inv.P = (B * Q - P * D) / det;
inv.Q = -(A * Q - P * C) / det;
return inv;
}
}
}
/// <summary>
/// (srcs) |-> (dsts)
/// </summary>
public void Add(Vector2 src, Vector2 dst)
{
srcs.Add(src);
dsts.Add(dst);
Calc();
return;
}
/// <summary>
/// (srcx, srcy) |-> (dstx,dsty)
/// </summary>
public void Add(double srcx,double srcy, double dstx, double dsty)
{
Vector2 vsrc = new Vector2(srcx, srcy);
Vector2 vdst = new Vector2(dstx, dsty);
srcs.Add(vsrc);
dsts.Add(vdst);
Calc();
return;
}
private void Calc()
{
if (srcs.Count > 2)
{
Affine myap = CalcGlobalAffine(srcs, dsts);
a = myap.A; b = myap.B; c = myap.C; d = myap.D; p = myap.P; q = myap.Q;
}
else if (srcs.Count == 2)
{
Affine myap = CalcGlobalHelmert(srcs, dsts);
a = myap.A; b = myap.B; c = myap.C; d = myap.D; p = myap.P; q = myap.Q;
}
return;
}
/// <summary>
/// コンソールに表示
/// </summary>
/// <returns>Affine instance</returns>
public void Print()
{
Console.Write(a.ToString("F8") + ", ");
Console.Write(b.ToString("F8") + ", ");
Console.Write(c.ToString("F8") + ", ");
Console.Write(d.ToString("F8") + ", ");
Console.Write(p.ToString("F4") + ", ");
Console.Write(q.ToString("F4") + "\n");
return;
}
/// <summary>
/// Affine変換の合成。this1to2 arg=0to1 で、0to2を返す
/// /// </summary>
/// <returns>Affine instance</returns>
public Affine Chain(Affine a01)
{
Affine a12 = new Affine(a,b,c,d,p,q);
var m01 = Matrix<double>.Build.Dense(3, 3, 0.0);
var m12 = Matrix<double>.Build.Dense(3, 3, 0.0);
m01[0, 0] = a01.A;
m01[0, 1] = a01.B;
m01[0, 2] = a01.P;
m01[1, 0] = a01.C;
m01[1, 1] = a01.D;
m01[1, 2] = a01.Q;
m01[2, 0] = 0;
m01[2, 1] = 0;
m01[2, 2] = 1.0;
m12[0, 0] = this.A;
m12[0, 1] = this.B;
m12[0, 2] = this.P;
m12[1, 0] = this.C;
m12[1, 1] = this.D;
m12[1, 2] = this.Q;
m12[2, 0] = 0;
m12[2, 1] = 0;
m12[2, 2] = 1.0;
var m02 = m12.Multiply(m01);
//Console.WriteLine(m01);
//Console.WriteLine(m12);
//Console.WriteLine(m02);
Affine a02 = new Affine(m02[0, 0], m02[0, 1], m02[1, 0], m02[1, 1], m02[0, 2], m02[1, 2]);
return a02;
}
/// <summary>
/// 元の座標群(srcs)から変換後の座標群(dsts)へ変換するためのアフィンパラメータを生成
/// public staticなので外からでも使える。
/// </summary>
/// <returns>Affine instance</returns>
public static Affine CalcGlobalAffine(List<Vector2> _srcs, List<Vector2> _dsts)
{
Affine ap = new Affine();
List<double> lorgx = new List<double>(from o in _srcs select o.X);
List<double> lorgy = new List<double>(from o in _srcs select o.Y);
List<double> ldstx = new List<double>(from d in _dsts select d.X);
List<double> ldsty = new List<double>(from d in _dsts select d.Y);
double[] abp = solve(lorgx, lorgy, ldstx);
ap.A = abp[0];
ap.B = abp[1];
ap.P = abp[2];
double[] cdq = solve(lorgx, lorgy, ldsty);
ap.C = cdq[0];
ap.D = cdq[1];
ap.Q = cdq[2];
return ap;
}
/// <summary>
/// 線形台数ライブラリMathNet.Numerics.LinearAlgebraを使用し連立方程式を解くprivate func.
/// </summary>
private static double[] solve(IList<double> ox, IList<double> oy, IList<double> v) {
var m = Matrix<double>.Build.Dense(3, 3, 0.0);
var b = Vector<double>.Build.Dense(3, 0.0);
for (int i = 0; i < ox.Count; i++) {
m[0, 0] += ox[i] * ox[i];
m[0, 1] += ox[i] * oy[i];
m[0, 2] += ox[i];
m[1, 0] += ox[i] * oy[i];
m[1, 1] += oy[i] * oy[i];
m[1, 2] += oy[i];
m[2, 0] += ox[i];
m[2, 1] += oy[i];
m[2, 2] += 1.0;
b[0] += v[i] * ox[i];
b[1] += v[i] * oy[i];
b[2] += v[i];
}
var x = m.Solve(b);
double[] p = new double[3];
p[0] = x[0];
p[1] = x[1];
p[2] = x[2];
return p;
}
/// <summary>
/// 元の2点から変換後の2点へ変換するためのHermartパラメータ(自由度4のAffineParams)を生成
/// public staticなので外からでも使える。
/// </summary>
/// <returns>Affine instance</returns>
public static Affine CalcGlobalHelmert(List<Vector2> _srcs, List<Vector2> _dsts)
{
Affine ap = new Affine();
List<double> lorgx = new List<double>(from o in _srcs select o.X);
List<double> lorgy = new List<double>(from o in _srcs select o.Y);
List<double> ldstx = new List<double>(from d in _dsts select d.X);
List<double> ldsty = new List<double>(from d in _dsts select d.Y);
//いろいろやる
return ap;
}
public static void usage()
{
//インスタンスの生成、変換点群の登録、と表示
Affine aff = new Affine();
aff.Add(132.5000,165.0140,-130.49674860,162.11975560);
aff.Add(-162.5000,165.0230,164.53275230,162.04025920);
aff.Add(162.5000,-164.9940,-160.53274940,-168.01124760);
aff.Add(-162.5010,-164.9730,164.50075280,-168.08773950);
aff.Print();
//Affine変換の合成
Affine a01 = new Affine();
Affine a12 = new Affine();
Affine a23 = new Affine();
//notation1
Vector2 v0 = new Vector2(1.1, 2.2);
Vector2 v1 = a01.Trans(v0);
Vector2 v2 = a12.Trans(v1);
Vector2 v3 = a23.Trans(v2);
//notation2
Affine a03 = a12.Chain( a12.Chain( a01 ) );
v3 = a03.Trans(v2);
//notation3
v3 = a12.Chain(a12.Chain(a01)).Trans(v0);
}
/*
* 未実装:保持している点群のなかから最寄の3点を使ってAffineパラメータを出すというシリーズ
/// <summary>
/// 逐次affineをLocalでもとめていく
/// </summary>
/// <returns>Affine instance</returns>
//public Affine ChainLocal(Affine ap01)
//{
// Affine ap12 = new Affine(a, b, c, d, p, q);
// Affine ap02 = new Affine();
// return ap02;
//}
/// <summary>
/// 指定した場所に近い3点の(srcs)から(dsts)を使ってパラメータを生成
/// </summary>
/// <returns>Affine instance</returns>
public Affine GetLocalAffine(Vector2 pos)
{
Affine ap = new Affine();
List<Vector2> localsrcs;
List<Vector2> localdsts;
return ap;
}
/// <summary>
/// 指定した場所に近い3点の(srcs)から(dsts)を使って変換
/// </summary>
/// <returns>Affine instance</returns>
public Vector2 TransLocal(Vector2 pos)
{
Vector2 dst = new Vector2();
List<Vector2> localsrcs;
List<Vector2> localdsts;
return dst;
}
/// <summary>
/// 指定した場所に近い3点の(srcs)から(dsts)を使ったアフィンパラメータで回転のみの変換
/// </summary>
/// <returns>Affine instance</returns>
public Vector2 TransRotLocal(Vector2 pos)
{
Vector2 dst = new Vector2();
List<Vector2> localsrcs;
List<Vector2> localdsts;
return dst;
}
*/
}
}
{
"CameraName": "SONY XC-HR300",
"Height": 440,
"Width": 512
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NagaraStage
{
public enum CoordType
{
stage = 0,
befdev = 1,
mod = 2,
mover = 3
}
//このクラスはインスタンスを1個しか生成させないようにして一意性を保証すべし。
//このクラスではAffineを保持する
//対応する座標値はそれぞれのAffineインスタンスが保持している
//今のところ値の読み込みに関する実装はこのクラスの外でやっている
public class Coordinate
{
//系全体を代表するAffine parameters
public Affine stage2befdev { get; private set; }
public Affine befdev2mod { get; private set; }
public Affine mod2mover { get; private set; }
public List<Affine> affinechain { get; private set; }
public Coordinate()
{
Initialize();
}
public void Initialize()
{
stage2befdev = new Affine();
befdev2mod = new Affine();
mod2mover = new Affine();
affinechain = new List<Affine>();
}
public void AddAffineChain(Affine af)
{
affinechain.Add(af);
Affine mover_to_pl01befdev = affinechain[0];
mod2mover = mover_to_pl01befdev.Inverse;
if(affinechain.Count == 1) return;
Affine plxxbefdev_to_pl01befdev = affinechain[1];
for(int i=2; i<affinechain.Count; i++)
{
plxxbefdev_to_pl01befdev = affinechain[i].Chain(plxxbefdev_to_pl01befdev);
}
befdev2mod = plxxbefdev_to_pl01befdev.Inverse;
}
/*
public Vector2 Trans(Vector2 v, CoordType src, CoordType dst)
{
switch (src)
{
case CoordType.stage:
{
Vector2 s = v;
if (dst == CoordType.stage) return s;
Vector2 b = stage2befdev.Trans(v);
if (dst == CoordType.befdev) return b;
Vector2 m = befdev2mod.Trans(b);
if (dst == CoordType.mod) return m;
Vector2 e = mover2mod.Trans(m);
if (dst == CoordType.mover) return e;
}
break;
case CoordType.befdev:
{
Vector2 b = v;
if (dst == CoordType.befdev) return b;
Vector2 m = befdev2mod.Trans(b);
if (dst == CoordType.mod) return m;
Vector2 e = mover2mod.Trans(m);
if (dst == CoordType.mover) return e;
Vector2 s = stage2befdev.Inverse.Trans(b);
if (dst == CoordType.stage) return s;
}
break;
case CoordType.mod:
{
Vector2 m = v;
if (dst == CoordType.mod) return m;
Vector2 e = mover2mod.Trans(m);
if (dst == CoordType.mover) return e;
Vector2 b = befdev2mod.Inverse.Trans(m);
if (dst == CoordType.befdev) return b;
Vector2 s = stage2befdev.Inverse.Trans(b);
if (dst == CoordType.stage) return s;
}
break;
case CoordType.mover:
{
Vector2 e = v;
if (dst == CoordType.mover) return v;
Vector2 m = mover2mod.Inverse.Trans(e);
if (dst == CoordType.mod) return m;
Vector2 b = befdev2mod.Inverse.Trans(m);
if (dst == CoordType.befdev) return b;
Vector2 s = stage2befdev.Inverse.Trans(b);
if (dst == CoordType.stage) return s;
}
break;
default:
return new Vector2(0, 0);
}//case
return new Vector2(0, 0);//値を返さないパスコードがあると言われるので。
}
*/
}
}
{
"Type": "thin",
"BaseThickness": 0.040,
"TypicalShs": [ 1.6, 1.6 ],
"OrigThickness": 0.390,
"PrevToThis": [
[132.5000,165.0140,-130.49674860,162.11975560],
[-162.5000,165.0230,164.53275230,162.04025920],
[162.5000,-164.9940,-160.53274940,-168.01124760],
[-162.5010,-164.9730,164.50075280,-168.08773950]
]
}
{
"Type": "thick",
"BaseThickness": 0.040,
"TypicalShs": [ 1.6, 1.6 ],
"OrigThickness": 1.002,
"PrevToThis": [
[155.0010,0.0140,155.19099800,-0.28604200],
[0.0500,155.0230,0.54990000,154.25793100],
[-155.5000,-0.0240,-154.68900000,-0.32392800],
[-0.0210,-154.9800,0.47904200,-154.81506000]
]
}
{
"Type": "thick",
"BaseThickness": 0.040,
"TypicalShs": [ 1.6, 1.6 ],
"OrigThickness": 1.003,
"PrevToThis": [
[154.9900,-0.0090,153.68005300,1.34403300],
[-0.0020,154.9950,0.39300100,154.79802900],
[-155.5040,0.0010,-154.32996500,0.42248100],
[0.0120,-155.0090,-0.52312300,-153.03590100],
]
}
{
"Type": "thick",
"BaseThickness": 0.040,
"TypicalShs": [ 1.6, 1.6 ],
"OrigThickness": 1.003,
"PrevToThis": [
[155.0020,0.0290,155.58203300,-0.08291500],
[0.0060,155.0020,0.43101400,155.51000000],
[-155.5100,-0.0010,-155.55102100,0.19750700],
[-0.0120,-155.0000,0.10297600,-155.42198800]
]
}
# -*- coding: utf-8 -*-
"""
@author: jyoshida
"""
if __name__ == '__main__':
print "==mover to pl01befdev======="
a = -1.0001
b = 0.0001
c = 0.0003
d = 1.0004
p = 2.000
q = -3.000
coords = [ (132.500, 165.014),
(-162.500, 165.023),
( 162.500, -164.994),
(-162.501, -164.973),
(0.111, 0.222),#for validation0
(166.666, 155.555),#for validation1
(-165.432, 170.000),#for validation2
(-144.444, -109.876),#for validation3
(100.000, -111.222)#for validation4
]
for co in coords:
x = co[0]
y = co[1]
X = a*x + b*y + p
Y = c*x + d*y + q
print "[{0:.4f},{1:.4f},{2:.8f},{3:.8f}]".format(x,y,X,Y)
#print "[{0:.4f},{1:.4f},{2:.4f},{3:.4f}]".format(x,y,X,Y)
print "==pl01befdev to pl02befdev======="
a = 0.998
b = 0.000
c = 0.000
d = 0.997
p = 0.500
q = -0.300
coords = [ (155.001, 0.014),
(0.050, 155.023),
(-155.500, -0.024),
(-0.021, -154.980),
(1.88901110,-2.77787790),#for validation0
(-164.66711110,152.66722180),#for validation1
(167.46554320,167.01837040),#for validation2
(146.44745680,-112.96328360),#for validation3
(-98.02112220,-114.23648880)#for validation4
]
for co in coords:
x = co[0]
y = co[1]
X = a*x + b*y + p
Y = c*x + d*y + q
print "[{0:.4f},{1:.4f},{2:.8f},{3:.8f}]".format(x,y,X,Y)
#print "[{0:.4f},{1:.4f},{2:.4f},{3:.4f}]".format(x,y,X,Y)
print "==pl02befdev to pl03befdev======="
a = 0.992
b = 0.003
c = 0.003
d = 0.993
p = -0.070
q = 0.888
coords = [ (154.990, -0.009),
(-0.002, 154.995),
(-155.504, 0.001),
(0.012, -155.009),
(2.38523308,-3.06954427),#for validation0
(-163.83777688,151.90922013),#for validation1
(167.63061211,166.21731529),#for validation2
(146.65456189,-112.92439375),#for validation3
(-97.32507996,-114.19377933)#for validation4
]
for co in coords:
x = co[0]
y = co[1]
X = a*x + b*y + p
Y = c*x + d*y + q
print "[{0:.4f},{1:.4f},{2:.8f},{3:.8f}]".format(x,y,X,Y)
#print "[{0:.4f},{1:.4f},{2:.4f},{3:.4f}]".format(x,y,X,Y)
print "==pl03befdev to pl04befdev======="
a = 1.002
b = 0.001
c = -0.001
d = 1.003
p = 0.270
q = 0.043
coords = [ (155.002, 0.029),
( 0.006, 155.002),
(-155.510, -0.001),
(-0.012, -155.000),
(2.28694258,-2.15290176),#for validation0
(-162.14134700,151.24234226),#for validation1
(166.71821916,166.44468592),#for validation2
(145.07255221,-110.80595931),#for validation3
(-96.95906066,-112.79839811)#for validation4
]
for co in coords:
x = co[0]
y = co[1]
X = a*x + b*y + p
Y = c*x + d*y + q
print "[{0:.4f},{1:.4f},{2:.8f},{3:.8f}]".format(x,y,X,Y)
#print "[{0:.4f},{1:.4f},{2:.4f},{3:.4f}]".format(x,y,X,Y)
print "==pl04befdev to stage======="
a = 1.0078
b = -0.0012
c = 0.0004
d = 1.0099
p = 0.002
q = -0.003
coords = [ (0.001, -0.002),
(150.002, 150.009),
( -149.996, 150.015),
(-150.020, -149.987),
(150.012, -150.000),
(2.55936356,-2.11864741),#for validation0
(-162.04438735,151.90121063),#for validation1
(167.48810028,166.82030176),#for validation2
(145.52189136,-111.24044974),#for validation3
(-96.99577718,-112.99683424)#for validation4
]
for co in coords:
x = co[0]
y = co[1]
X = a*x + b*y + p
Y = c*x + d*y + q
print "[{0:.4f},{1:.4f},{2:.8f},{3:.8f}]".format(x,y,X,Y)
#print "[{0:.4f},{1:.4f},{2:.4f},{3:.4f}]".format(x,y,X,Y)
"""
==mover to pl01befdev=======
[132.5000,165.0140,-130.49674860,162.11975560]
[-162.5000,165.0230,164.53275230,162.04025920]
[162.5000,-164.9940,-160.53274940,-168.01124760]
[-162.5010,-164.9730,164.50075280,-168.08773950]
[0.1110,0.2220,1.88901110,-2.77787790]
[166.6660,155.5550,-164.66711110,152.66722180]
[-165.4320,170.0000,167.46554320,167.01837040]
[-144.4440,-109.8760,146.44745680,-112.96328360]
[100.0000,-111.2220,-98.02112220,-114.23648880]
==pl01befdev to pl02befdev=======
[155.0010,0.0140,155.19099800,-0.28604200]
[0.0500,155.0230,0.54990000,154.25793100]
[-155.5000,-0.0240,-154.68900000,-0.32392800]
[-0.0210,-154.9800,0.47904200,-154.81506000]
[1.8890,-2.7779,2.38523308,-3.06954427]
[-164.6671,152.6672,-163.83777688,151.90922013]
[167.4655,167.0184,167.63061211,166.21731529]
[146.4475,-112.9633,146.65456189,-112.92439375]
[-98.0211,-114.2365,-97.32507996,-114.19377933]
==pl02befdev to pl03befdev=======
[154.9900,-0.0090,153.68005300,1.34403300]
[-0.0020,154.9950,0.39300100,154.79802900]
[-155.5040,0.0010,-154.32996500,0.42248100]
[0.0120,-155.0090,-0.52312300,-153.03590100]
[2.3852,-3.0695,2.28694258,-2.15290176]
[-163.8378,151.9092,-162.14134700,151.24234226]
[167.6306,166.2173,166.71821916,166.44468592]
[146.6546,-112.9244,145.07255221,-110.80595931]
[-97.3251,-114.1938,-96.95906066,-112.79839811]
==pl03befdev to pl04befdev=======
[155.0020,0.0290,155.58203300,-0.08291500]
[0.0060,155.0020,0.43101400,155.51000000]
[-155.5100,-0.0010,-155.55102100,0.19750700]
[-0.0120,-155.0000,0.10297600,-155.42198800]
[2.2869,-2.1529,2.55936356,-2.11864741]
[-162.1413,151.2423,-162.04438735,151.90121063]
[166.7182,166.4447,167.48810028,166.82030176]
[145.0726,-110.8060,145.52189136,-111.24044974]
[-96.9591,-112.7984,-96.99577718,-112.99683424]
==pl04befdev to stage=======
[0.0010,-0.0020,0.00301020,-0.00501940]
[150.0020,150.0090,150.99400480,151.55108990]
[-149.9960,150.0150,-151.34398680,151.43715010]
[-150.0200,-149.9870,-151.00817160,-151.53487930]
[150.0120,-150.0000,151.36409360,-151.42799520]
[2.5594,-2.1186,2.58386897,-2.14159827]
[-162.0444,151.9012,-163.48861502,153.33721486]
[167.4881,166.8203,168.59632310,168.53581799]
[145.5219,-111.2404,146.79245065,-112.28652144]
[-96.9958,-112.9968,-97.61474804,-114.15730121]
"""
{
"Lenses": [
{
"Mag": 10,
"Dimensions": [ 0.500, 0.500, 0.003 ],
"Offsets": [ 0.010, -0.020 ],
"LEDParam": 100,
"Time": "2016/09/01 10:00:00"
},
{
"Mag": 50,
"Dimensions": [ 0.125, 0.110, 0.003 ],
"Offsets": [ 0.000, 0.000 ],
"LEDParam": 100,
"Time": "2016/09/01 10:00:00"
}
]
}
{
"LimitPol": 252,
"EncoderResolutions": [ 0.001, 0.001, 0.0001 ],
"MotorResolutions": [ 0.001, 0.001, 0.0001 ],
"MotorInitialVelocities": [ 30, 30, 2 ],
"MotorAccels": [ 1, 2, 3 ],
"MotorSpeed1": [ 0.03, 0.03, 0.01 ],
"MotorSpeed2": [ 0.1, 0.1, 0.02 ],
"MotorSpeed3": [ 10, 10, 0.07 ],
"MotorSpeed4": [ 30, 30, 0.4 ],
"LEDCOMPort": "COM1",
"_comment": "comment here"
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Newtonsoft.Json;//Json.NET
using System.ComponentModel;//DefaultValue for Json.NET
using System.IO;
namespace NagaraStage
{
public class StageInfo
{
public string Location { get; set; }
public int ID { get; set; }
public string CPU { get; set; }
public string OS { get; set; }
public string MEM { get; set; }
}
public class Lens
{
public int Mag { get; set; }
public List<double> Dimensions { get; set; }
public List<double> Offsets { get; set; }
public int LEDParam { get; set; }
public string Time { get; set; }
}
public class LensDB
{
public List<Lens> Lenses { get; set; }
public Lens GetLens(int mag)
{
for (int i = 0; i < Lenses.Count; i++)
{
if (Lenses[i].Mag == mag) return Lenses[i];
}
throw new Exception("no such lens");
}
}
public class CamParams
{
public string CameraName { get; set; }
public int Height { get; set; }
public int Width { get; set; }
}
public class Mecha
{
public int LimitPol { get; set; }//典型的値:252.(さらに以前は16進数でFCと記述されていた.)
public List<double> EncoderResolutions { get; set; }
public List<double> MotorResolutions { get; set; }
public List<double> MotorInitialVelocities { get; set; }
public List<int> MotorAccels { get; set; }
public List<double> MotorSpeed1 { get; set; }
public List<double> MotorSpeed2 { get; set; }
public List<double> MotorSpeed3 { get; set; }
public List<double> MotorSpeed4 { get; set; }
public string LEDCOMPort { get; set; }
public Vector3 EncoderResolution//エンコーダの分解能
{
get { return new Vector3(EncoderResolutions[0], EncoderResolutions[1], EncoderResolutions[2]); }
}
public Vector3 MotorResolution//モータの1パルスあたりの進む距離
{
get { return new Vector3(MotorResolutions[0], MotorResolutions[1], MotorResolutions[2]); }
}
public Vector3 MotorInitialVelocity//モータの初速度を取得
{
get { return new Vector3(MotorInitialVelocities[0], MotorInitialVelocities[1], MotorInitialVelocities[2]); }
}
public Vector3 VMotorAccels//モータの加速度
{
get { return new Vector3(MotorAccels[0], MotorAccels[1], MotorAccels[2]); }
}
public Vector3 VMotorSpeed1
{
get { return new Vector3(MotorSpeed1[0], MotorSpeed1[1], MotorSpeed1[2]); }
}
public Vector3 VMotorSpeed2
{
get { return new Vector3(MotorSpeed2[0], MotorSpeed2[1], MotorSpeed2[2]); }
}
public Vector3 VMotorSpeed3
{
get { return new Vector3(MotorSpeed3[0], MotorSpeed3[1], MotorSpeed3[2]); }
}
public Vector3 VMotorSpeed4
{
get { return new Vector3(MotorSpeed4[0], MotorSpeed4[1], MotorSpeed4[2]); }
}
}
public class CommonInfo
{
public string PlsetDir { get; set; }//測定した表面座標やgridの対応表を保存するディレクトリ
public string ParamsDir { get; set; }//個々の乾板の情報ファイルが収められているディレクトリ
public string GridBeforeDev { get; set; }//ネガの穴の位置を鏡像反転したデータのファイル
public string GridAfterDevSuffix { get; set; }//現像後座標系のマークの位置を収めたファイルの接尾語
}
public class EmulsionInfo
{
public string Type { get; set; }
public double BaseThickness { get; set; }
public List<double> TypicalShs { get; set; }
public double OrigThickness { get; set; }
public List<List<double>> PrevToThis { get; set; }
}
public class MarkMeas
{
public double befdevx { get; set; }
public double befdevy { get; set; }
public double stagex { get; set; }
public double stagey { get; set; }
public string Time { get; set; }
}
public class Plset
{
public string Time { get; set; }
public List<MarkMeas> MarkMeass { get; set; }
}
/*このクラスは、外部ファイルから読み込んで使う系のパラメータを一括で管理する
* このクラスは、Appクラスの直下のメンバーとしてインスタンス化される。
* かつてParameterManagerというクラスが存在して、
* バージョンの過渡期に名前が被らないようにParamManagerとなづけた。
*/
public class ParamManager
{
string SysParamDir;
public StageInfo stageinfo { get; private set; }//システムの情報
public LensDB lensdb { get; private set; }//レンズ類のデータベース的なクラス
public CamParams camparams { get; private set; } //カメラのパラメータ
public Mecha mecha { get; private set; } //モーター類の設定
public CommonInfo commoninfo { get; private set; }
public EmulsionInfo emulsioninfo { get; private set; }
public List<EmulsionInfo> listemulsioninfo { get; private set; }
public Lens lens;//その時点の主光学系のレンズ
public Plset plset;//grid測定のデータ
public string exp { get; private set; }
public int mod { get; private set; }
public int pl { get; private set; }
public string gridbeforedev { get; private set; }
public string gridafterdev { get; private set; }
public string plsetjson { get; private set; }
public ParamManager(string _SysParamDir)
{
try
{
SysParamDir = _SysParamDir;
string text;
text = File.ReadAllText(SysParamDir + "\\stageinfo.json");
stageinfo = JsonConvert.DeserializeObject<StageInfo>(text);
text = File.ReadAllText(SysParamDir + "\\lenses.json");
lensdb = JsonConvert.DeserializeObject<LensDB>(text);
text = File.ReadAllText(SysParamDir + "\\camparams.json");
camparams = JsonConvert.DeserializeObject<CamParams>(text);
text = File.ReadAllText(SysParamDir + "\\mechaparams.json");
mecha = JsonConvert.DeserializeObject<Mecha>(text);
lens = lensdb.GetLens(10);//default x10 lens
commoninfo = new CommonInfo();
emulsioninfo = new EmulsionInfo();
listemulsioninfo = new List<EmulsionInfo>();
plset = new Plset();
exp = "";
mod = 0;
pl = 0;
gridbeforedev = "";
gridafterdev = "";
plsetjson = "";
}
catch (Exception e)
{
throw e;
}
}
public void ReadCommonInfo(string jsonfilenamefullpath)
{
try
{
string text;
text = File.ReadAllText(jsonfilenamefullpath);
commoninfo = JsonConvert.DeserializeObject<CommonInfo>(text);
}
catch (Exception e)
{
throw e;
}
}
public void ReadEmulsionInfo(string jsonfilenamefullpath)
{
try
{
//jsonfilenamefullpath is lilke "E07_014_01.json";
string[] stArrayPath = jsonfilenamefullpath.Split('\\');
int indexlast = stArrayPath.Length;
string jsonfilename = stArrayPath[indexlast - 1];
string[] stArrayFile = jsonfilename.Split('.');
string[] stArrayData = stArrayFile[0].Split('_');
exp = stArrayData[0];
mod = int.Parse(stArrayData[1]);
pl = int.Parse(stArrayData[2]);
string text;
text = File.ReadAllText(jsonfilenamefullpath);
emulsioninfo = JsonConvert.DeserializeObject<EmulsionInfo>(text);
gridbeforedev = commoninfo.ParamsDir + "\\" + commoninfo.GridBeforeDev;
gridafterdev = commoninfo.ParamsDir + "\\" + stArrayFile[0] + commoninfo.GridAfterDevSuffix;
plsetjson = commoninfo.PlsetDir + "\\_plset.json";
for (int i = 1; i <= pl; i++)
{
string myjson = "";
myjson += commoninfo.ParamsDir;
myjson += "\\";
myjson += exp + "_";
myjson += mod.ToString("D3") + "_";
myjson += i.ToString("D2") + ".json";
text = File.ReadAllText(myjson);
EmulsionInfo myemulinfo = JsonConvert.DeserializeObject<EmulsionInfo>(text);
listemulsioninfo.Add(myemulinfo);
}
}
catch (Exception e)
{
throw e;
}
}
public void ReadPlsetInfo()
{
try
{
//jsonfilenamefullpath is lilke "E07_014_01.json";
string text;
text = File.ReadAllText(plsetjson);
plset = JsonConvert.DeserializeObject<Plset>(text);
}
catch (Exception e)
{
throw e;
}
}
}
}//namespace
{
"Time": "2016/09/01 10:00:00",
"Marks": [
{ "befdevx": 0.000, "befdevy": 0.000, "stagex": 0.000, "stagey": 0.000, "Time": "2016/09/01 10:01:00" },
{ "befdevx": 10.025, "befdevy": 30.040, "stagex": 10.020, "stagey": 30.030, "Time": "2016/09/01 10:02:00" }
]
}
{
"Time": "2016/09/02 10:00:00",
"MarkMeass": [
{ "befdevx":0.0010, "befdevy":-0.0020, "stagex":0.00301020, "stagey":-0.00501940, "Time": "2016/09/01 10:01:00" },
{ "befdevx":150.0020, "befdevy":150.0090, "stagex":150.99400480, "stagey":151.55108990, "Time": "2016/09/01 10:02:00" },
{ "befdevx":-149.9960, "befdevy":150.0150, "stagex":-151.34398680, "stagey":151.43715010, "Time": "2016/09/01 10:03:00" },
{ "befdevx":-150.0200, "befdevy":-149.9870, "stagex":-151.00817160, "stagey":-151.53487930, "Time": "2016/09/01 10:04:00" },
{ "befdevx":150.0120, "befdevy":-150.0000, "stagex":151.36409360, "stagey":-151.42799520, "Time": "2016/09/01 10:05:00" }
]
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using NagaraStage;
namespace NagaraStage
{
class Program
{
//ParamManagerとCoordinateを利用するサンプル
static void Main(string[] args)
{
try
{
//パラムマネージャを生成するときに、
//stageinfo.json, lenses.json, camparams.json, mechaparams.json
//の4つのjsonファイルがあるディレクトリを指定。(必須)
//これはアプリケーションの起動時に勝手に名前固定のファイルを読み込んで行うこととする。
ParamManager pm = new ParamManager(@"C:\sysparam");
//以下アクセスの方法を示したサンプル。
//コンソールに書き出す。
Console.WriteLine("pm.stageinfo.ID: " + pm.stageinfo.ID);
Console.WriteLine("pm.stageinfo.CPU: " + pm.stageinfo.CPU);
for (int i = 0; i < pm.lensdb.Lenses.Count; i++)
{
Lens l = pm.lensdb.Lenses[i];
Console.WriteLine("lens: " + l.Mag + ", " + l.Dimensions[0] + ", " + l.Dimensions[1], l.Offsets[1]);
}
Console.WriteLine("pm.camparams.CameraName: " + pm.camparams.CameraName);
Console.WriteLine("pm.camparams.Height: " + pm.camparams.Height);
Console.WriteLine("pm.camparams.Width:" + pm.camparams.Width);
Console.WriteLine("pm.mecha.MotorResolutions[0]: " + pm.mecha.MotorResolutions[0]);
Console.WriteLine("pm.mecha.MotorResolutions[1]: " + pm.mecha.MotorResolutions[1]);
Console.WriteLine("pm.mecha.MotorResolutions[2]: " + pm.mecha.MotorResolutions[2]);
//次に乾板の情報が記載されたjsonファイルを読み込む。(フルパスで指定)
//これは「新規ステージ操作開始」の際にやること。
//ビーム照射ごとに共通する情報はCommonInfoの中に入れてある。
//基本的にはEmulsionInfoを見たい乾板に応じてそのつど変えればよい。
//EmulsionInfoのファイル名は実験名_mod番号_pl番号というフォーマットにする。NagaraStageはこの情報を使う。
pm.ReadCommonInfo(@"C:\emscan\E07\params\run2016.json");
pm.ReadEmulsionInfo(@"C:\emscan\E07\params\E07_200_04.json");
Console.WriteLine("pm.exp: " + pm.exp);
Console.WriteLine("pm.mod: " + pm.mod);
Console.WriteLine("pm.pl: " + pm.pl);
//pm.pl = 4;//forbidden. setter function is private.
Console.WriteLine("pm.lens.Dimensions[0]: " + pm.lens.Dimensions[0]);
Console.WriteLine("pm.lens.Dimensions[1]: " + pm.lens.Dimensions[1]);
Console.WriteLine("pm.lens.Dimensions[2]: " + pm.lens.Dimensions[2]);
Console.WriteLine("pm.lens.Mag: " + pm.lens.Mag);
Console.WriteLine("pm.lens.Time: " + pm.lens.Time);
Console.WriteLine("pm.GridBeforeDev: " + pm.gridbeforedev);
Console.WriteLine("pm.GridAfterDev: " + pm.gridafterdev);
//
//Coordinate
//
Coordinate co = new Coordinate();
//デフォルトでは (1,0,0,1,0,0)
Console.WriteLine("co.stage2befdev.A: " + co.stage2befdev.A);
Console.WriteLine("co.stage2befdev.B: " + co.stage2befdev.B);
Console.WriteLine("co.stage2befdev.C: " + co.stage2befdev.C);
Console.WriteLine("co.stage2befdev.D: " + co.stage2befdev.D);
Console.WriteLine("co.stage2befdev.P: " + co.stage2befdev.P);
Console.WriteLine("co.stage2befdev.Q: " + co.stage2befdev.Q);
co.stage2befdev.Print();
//こういうことが出来てしまうのを禁止したいのだが・・・
//accessibilityをprotected とかにすればいいのか?
co.stage2befdev.A = 9.9;
Console.WriteLine("co.stage2befdev.A: " + co.stage2befdev.A);
co.stage2befdev.A = co.stage2befdev.B;
Console.WriteLine("co.stage2befdev.A: " + co.stage2befdev.A);
//grid測定を読み込む
Console.WriteLine("pm.GridAfterDev: " + pm.plsetjson);
pm.ReadPlsetInfo();//案1:マークの測定点が増えたらそのつど読み込む 案2:pmに測定情報を内部で持たせておく 案1のほうが楽か。
foreach (MarkMeas mm in pm.plset.MarkMeass)
{
Console.Write("add: ");
Console.Write(mm.stagex.ToString() + ", ");
Console.Write(mm.stagey.ToString() + ", ");
Console.Write(mm.befdevx.ToString() + ", ");
Console.Write(mm.befdevy.ToString() + "\n");
co.stage2befdev.Add(mm.stagex, mm.stagey, mm.befdevx, mm.befdevy);
}
//ステージ座標上から現像前座標への変換
Console.WriteLine("stage2befdev: ");
co.stage2befdev.Print();
co.stage2befdev.Inverse.Print();
//いまのplから上流のplのjsonファイルを全て読む
foreach (EmulsionInfo ei in pm.listemulsioninfo)
{
Affine af = new Affine();
foreach (List<double> ld in ei.PrevToThis)
{
Console.Write("add: ");
Console.Write(ld[0].ToString() + ", ");
Console.Write(ld[1].ToString() + ", ");
Console.Write(ld[2].ToString() + ", ");
Console.Write(ld[3].ToString() + "\n");
af.Add(ld[0], ld[1], ld[2], ld[3]);
}
co.AddAffineChain(af);
af.Print();
af.Inverse.Print();
}
//現像前座標系からpl01の現像前座標系(module座標系)への変換
Console.WriteLine("befdev2mod: ");
co.befdev2mod.Print();
co.befdev2mod.Inverse.Print();
//mod座標系からmover座標系への変換
Console.WriteLine("mod2mover: ");
co.mod2mover.Print();
co.mod2mover.Inverse.Print();
List<Vector2> lvalstage = new List<Vector2>();
Vector2 v0 = new Vector2(2.58386897,-2.14159827);
Vector2 v1 = new Vector2(-163.48861502,153.33721486);
Vector2 v2 = new Vector2(168.59632310,168.53581799);
Vector2 v3 = new Vector2(146.79245065,-112.28652144);
Vector2 v4 = new Vector2(-97.61474804, -114.15730121);
lvalstage.Add(v0);
lvalstage.Add(v1);
lvalstage.Add(v2);
lvalstage.Add(v3);
lvalstage.Add(v4);
List<Vector2> lvalbefdev = new List<Vector2>();
Console.WriteLine("stage2befdev: val points pl4stage -> pl4befdev");
foreach(Vector2 v in lvalstage){
Vector2 b = co.stage2befdev.Trans(v);
lvalbefdev.Add(b);
Console.WriteLine("{0} {1}", b.X.ToString("F3"), b.Y.ToString("F3"));
}
List<Vector2> lvalmod = new List<Vector2>();
Console.WriteLine("befdev2mod: val points pl4befdev -> pl1befdev(module_coordinate)");
foreach (Vector2 v in lvalbefdev)
{
Vector2 m = co.befdev2mod.Trans(v);
lvalmod.Add(m);
Console.WriteLine("{0} {1}", m.X.ToString("F3"), m.Y.ToString("F3"));
}
List<Vector2> lvalmover = new List<Vector2>();
Console.WriteLine("mod2mover: val points pl1befdev(module_coordinate) -> mover");
foreach (Vector2 v in lvalmod)
{
Vector2 e = co.mod2mover.Trans(v);
lvalmover.Add(e);
Console.WriteLine("{0} {1}", e.X.ToString("F3"), e.Y.ToString("F3"));
}
//目視でみて変換の計算が正しいことを確認した。
//いづれこの計算をテストコードとしてまとめる。
//Affine.usage();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
//https://msdn.microsoft.com/ja-jp/library/system.diagnostics.stacktrace(v=vs.110).aspx
StackTrace st = new StackTrace(true);
for (int i = 0; i < st.FrameCount; i++)
{
// Note that high up the call stack, there is only
// one stack frame.
StackFrame sf = st.GetFrame(i);
Console.WriteLine("{0} {1} {2}",
sf.GetMethod(),
sf.GetFileName(),
sf.GetFileLineNumber());
}
}
}
}
}
{
"PlsetDir": "C:\\emscan\\E07\\plset",
"ParamsDir": "C:\\emscan\\E07\\params",
"GridBeforeDev": "E07grid1.txt",
"GridAfterDevSuffix": "_gridmarks.txt"
}
{
"Location": "Gif",
"ID": 10,
"CPU": "Corei5-2.0GHz",
"OS": "Win7",
"MEM": "4GB",
"_comment": "comment here"
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace NagaraStage {
/// <summary>方向を表す列挙体です.</summary>
public enum VectorId {
/// <summary>
/// X軸,X方向を示します.
/// </summary>
X = 0,
/// <summary>
/// Y軸,Y方向を示します.
/// </summary>
Y = 1,
/// <summary>
/// Z軸,Z方向を示します.
/// </summary>
Z = 2
}
/// <summary>
/// 2次元ベクトル(x, y)のdouble型構造体です.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct Vector2 {
/// <summary>
/// X方向の値
/// </summary>
public double X;
/// <summary>
/// Y方向の値
/// </summary>
public double Y;
/// <summary>
/// Initializes a new instance of the <see cref="Vector2" /> struct.
/// </summary>
/// <param name="x">The x.</param>
/// <param name="y">The y.</param>
public Vector2(double x, double y) {
this.X = x;
this.Y = y;
}
public static Vector2 operator+(Vector2 a, Vector2 b) {
return new Vector2(a.X + b.X, a.Y + b.Y);
}
public static Vector2 operator -(Vector2 a, Vector2 b) {
return new Vector2(a.X - b.X, a.Y - b.Y);
}
public static bool operator >(Vector2 a, Vector2 b) {
return (a.X > b.X && a.Y > b.Y);
}
public static bool operator <(Vector2 a, Vector2 b) {
return (a.X < b.X && a.Y < b.Y);
}
public static bool operator >=(Vector2 a, Vector2 b) {
return (a.X >= b.X && a.Y >= b.Y);
}
public static bool operator <=(Vector2 a, Vector2 b) {
return (a.X <= b.X && a.Y <= b.Y);
}
public static bool operator ==(Vector2 a, Vector2 b) {
return (a.X == b.X && a.Y == b.Y);
}
public static bool operator !=(Vector2 a, Vector2 b) {
return (a.X != b.X || a.Y != b.Y);
}
/// <summary>
/// 取り出します.
/// </summary>
/// <param name="vectorId">方向</param>
/// <returns>引数で与えられた方向の値</returns>
public double Index(VectorId vectorId) {
double val = 0;
switch ((int)vectorId) {
case (int)VectorId.X:
val = X;
break;
case (int)VectorId.Y:
val = Y;
break;
}
return val;
}
}
/// <summary>2次元ベクトル(x, y)のint型構造体です.</summary>
public struct Vector2Int {
/// <summary>X方向の値</summary>
public int X;
/// <summary>Y方向の値</summary>
public int Y;
/// <summary>
/// Initializes a new instance of the <see cref="Vector2Int" /> struct.
/// </summary>
/// <param name="x">The x.</param>
/// <param name="y">The y.</param>
public Vector2Int(int x, int y) {
this.X = x;
this.Y = y;
}
/// <summary>
/// 特定方向の成分を取り出します.
/// </summary>
/// <param name="vectorId">方向</param>
/// <returns>引数で与えられた方向の値</returns>
public int Index(VectorId vectorId) {
int val = 0;
switch ((int)vectorId) {
case (int)VectorId.X:
val = X;
break;
case (int)VectorId.Y:
val = Y;
break;
}
return val;
}
}
/// <summary>
/// 2次元ベクトル(x, y)と角度(angle)を保持するクラスです.
/// </summary>
public struct Vector2Angle {
public double X;
public double Y;
public double Angle;
public Vector2Angle(double x, double y, double angle) {
this.X = x;
this.Y = y;
this.Angle = angle;
}
}
/// <summary>
/// 3次元ベクトル(x, y, z)のdouble型構造体です.
/// </summary>
public struct Vector3 {
/// <summary>
/// X方向の値
/// </summary>
public double X;
/// <summary>
/// Y方向の値
/// </summary>
public double Y;
/// <summary>
/// Z方向の値
/// </summary>
public double Z;
public static Vector3 operator +(Vector3 a, Vector3 b) {
return new Vector3(a.X + b.X, a.Y + b.Y, a.Z + b.Z);
}
public static Vector3 operator -(Vector3 a, Vector3 b) {
return new Vector3(a.X - b.X, a.Y - b.Y, a.Z - b.Z);
}
public static bool operator >(Vector3 a, Vector3 b) {
return (a.X > b.X && a.Y > b.Y && a.Z > b.Z);
}
public static bool operator <(Vector3 a, Vector3 b) {
return (a.X < b.X && a.Y < b.Y && a.Z < b.Z);
}
public static bool operator >=(Vector3 a, Vector3 b) {
return (a.X >= b.X && a.Y >= b.Y);
}
public static bool operator <=(Vector3 a, Vector3 b) {
return (a.X <= b.X && a.Y <= b.Y && a.Z <= b.Z);
}
public static bool operator ==(Vector3 a, Vector3 b) {
return (a.X == b.X && a.Y == b.Y && a.Z == b.Z);
}
public static bool operator !=(Vector3 a, Vector3 b) {
return (a.X != b.X || a.Y != b.Y || a.Z != b.Z);
}
public Vector3 ToAbs() {
return new Vector3(Math.Abs(X), Math.Abs(Y), Math.Abs(Z));
}
/// <summary>
/// Initializes a new instance of the <see cref="Vector3" /> struct.
/// </summary>
/// <param name="x">The x.</param>
/// <param name="y">The y.</param>
/// <param name="z">The z.</param>
public Vector3(double x, double y, double z) {
this.X = x;
this.Y = y;
this.Z = z;
}
/// <summary>
/// 特定方向の成分を取り出します.
/// </summary>
/// <param name="vectorId">方向</param>
/// <returns>引数で与えられた方向の値</returns>
public double Index(VectorId vectorId) {
double val = 0;
switch ((int)vectorId) {
case (int)VectorId.X:
val = X;
break;
case (int)VectorId.Y:
val = Y;
break;
case (int)VectorId.Z:
val = Z;
break;
}
return val;
}
}
/// <summary>
/// 3次元ベクトル(x, y, z)のint型構造体です.
/// </summary>
public struct Vector3Int {
/// <summary>
/// X方向の値
/// </summary>
public int X;
/// <summary>
/// Y方向の値
/// </summary>
public int Y;
/// <summary>
/// Z方向の値
/// </summary>
public int Z;
/// <summary>
/// Initializes a new instance of the <see cref="Vector3Int" /> struct.
/// </summary>
/// <param name="x">The x.</param>
/// <param name="y">The y.</param>
/// <param name="z">The z.</param>
public Vector3Int(int x, int y, int z) {
this.X = x;
this.Y = y;
this.Z = z;
}
/// <summary>
/// 特定方向の成分を取り出します.
/// </summary>
/// <param name="vectorId">方向</param>
/// <returns>引数で与えられた方向の値</returns>
public int Index(VectorId vectorId) {
int val = 0;
switch ((int)vectorId) {
case (int)VectorId.X:
val = X;
break;
case (int)VectorId.Y:
val = Y;
break;
case (int)VectorId.Z:
val = Z;
break;
}
return val;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment