// GlassAlign.h: interface for the CGlassAlign class.
|
//
|
//////////////////////////////////////////////////////////////////////
|
|
#if !defined(AFX_GLASSALIGN_H__A4EDE408_69C7_440F_9842_CCDFAA98048A__INCLUDED_)
|
#define AFX_GLASSALIGN_H__A4EDE408_69C7_440F_9842_CCDFAA98048A__INCLUDED_
|
|
#include "Math.h"
|
|
|
#if _MSC_VER > 1000
|
#pragma once
|
#endif // _MSC_VER > 1000
|
|
|
|
// ¿øÁ¡ÀÇ À§Ä¡ ¿Í xÃàÀÇ ¹æÇâ¿¡ ´ëÇÑ Á¤ÀÇ.
|
// ¹Ý ½Ã°è¹æÇâ ¼³Á¤, ¼øÂ÷ÀûÀ¸·Î ¾Õ¼ø¼ÀÇ µÞÀÚ¸¦ ½ÃÀÛ ±ÛÀÚ·Î ÁöÁ¤.
|
enum OriginPos{OP_LEFT_TOP, OP_LEFT_BOTTOM, OP_RIGHT_BOTTOM, OP_RIGHT_TOP, OP_COUNT};
|
enum XDirection{XD_HORIZONTAL= 0, XD_VERTICAL= 1, XD_COUNT};
|
|
|
|
template <typename TTT>
|
class CCoordSystem
|
{
|
public:
|
OriginPos m_OriginPos;
|
XDirection m_XDirection;
|
TTT m_Width;
|
TTT m_Height;
|
|
public:
|
CCoordSystem()
|
{
|
m_OriginPos= OP_LEFT_TOP;
|
m_XDirection= XD_HORIZONTAL;
|
m_Width= 0;
|
m_Height= 0;
|
}
|
CCoordSystem(OriginPos pos, XDirection xDir, TTT width, TTT height)
|
{
|
SetSystem(pos, xDir, width, height);
|
}
|
void SetSystem(OriginPos pos, XDirection xDir, TTT width, TTT height)
|
{
|
m_OriginPos = pos;
|
m_XDirection = xDir;
|
m_Width = width;
|
m_Height = height;
|
}
|
|
BOOL operator ==(CCoordSystem<TTT> &comp)
|
{
|
return m_OriginPos == comp.m_OriginPos && m_XDirection == comp.m_XDirection;
|
}
|
};
|
|
// x¿Í yÀÇ ºÎÈ£ º¯È¯,, x¿Í yÀÇ Ä¡È¯Àº xÃàÀÇ ¹æÇâ º¸°í °áÁ¤.
|
static int transx[4][4][2]= { {{1, 1}, {1, -1}, {-1, -1}, {-1, 1}} // 1 : (1~4) = Src(1) : Target(1~4)
|
,{{1, -1}, {1, 1}, {-1, 1}, {-1, -1}} // 2 : (1~4)
|
,{{-1, -1}, {-1, 1}, {1, 1}, {1, -1}} // 3 : (1~4)
|
,{{-1, 1}, {-1, -1}, {1, -1}, {1, 1}} // 4 : (1~4)
|
};
|
|
|
// [pox, xdir]ÀÇ °öÀ¸·Î ÁÂÇ¥°è º¯È¯ÀÇ °á°ú¸¦ ¹Ý¿µÇÑ´Ù.
|
// [LEFT_BOTTOM, XD_HORIZONTAL]=1, ¿¡¼ [RIGHT_BOTTOM, XD_VERTICAL]= 1 À̸é 1*1 = 1 À̵ǹǷΠTHETAÀÇ ÇÕÀÌ ÃÖÁ¾ THETA°ªÀÌ µÈ´Ù.
|
static int thetasign[4][2]= {{-1, 1}, {1, -1}, {-1, 1}, {1, -1} };
|
|
|
#define TRANS_PT(trans, pt, targetPt) trans.TransToTarget(pt.x, pt.y, targetPt.x, targetPt.y);
|
#define ROTATE_PT(trans, pt, targetPt) trans.RotateToTarget(pt.x, pt.y, targetPt.x, targetPt.y);
|
|
template <typename TTT>
|
class CCoordTrans
|
{
|
CCoordSystem<TTT> m_SrcSystem;
|
CCoordSystem<TTT> m_TargetSystem;
|
|
|
int a, b, width, height;// ¹æÇâ Àüȯ¿ë flag
|
|
public:
|
BOOL IsNeedeToTrans()
|
{
|
if(m_SrcSystem == m_TargetSystem)
|
return FALSE;// ÁÂÇ¥°è°¡ °°À¸¸é º¯È¯ ÇÊ¿ä ¾øÀ½.
|
return TRUE;
|
}
|
|
BOOL SetTransSystem(OriginPos srcPos, XDirection srcXDir, TTT width, TTT height, OriginPos targetPos, XDirection targetXDir)
|
{
|
m_SrcSystem.SetSystem(srcPos, srcXDir, width, height);
|
m_TargetSystem.SetSystem(targetPos, targetXDir, width, height);
|
SetTransSystem(m_SrcSystem, m_TargetSystem);
|
|
return IsNeedeToTrans();
|
}
|
|
BOOL SetTransSystem(CCoordSystem<TTT> &src, CCoordSystem<TTT> &target)
|
{
|
m_SrcSystem= src;
|
m_TargetSystem= target;
|
|
|
// x= a*x+ width;
|
// y= b*y+ height;
|
|
|
if(m_SrcSystem.m_XDirection == XD_HORIZONTAL)// HORIZONTALÀ» ±âÁØÀ¸·Î Å×ÀÌºí ¸¸µé¾îÁü.
|
{
|
a= transx[m_SrcSystem.m_OriginPos][m_TargetSystem.m_OriginPos][0];
|
b= transx[m_SrcSystem.m_OriginPos][m_TargetSystem.m_OriginPos][1];
|
}else
|
{
|
b= transx[m_SrcSystem.m_OriginPos][m_TargetSystem.m_OriginPos][0];
|
a= transx[m_SrcSystem.m_OriginPos][m_TargetSystem.m_OriginPos][1];
|
}
|
|
|
if(a < 0)
|
width= m_SrcSystem.m_Width;
|
else
|
width= 0;
|
|
if(b < 0)
|
height= m_SrcSystem.m_Height;
|
else
|
height= 0;
|
|
if(m_SrcSystem.m_XDirection == m_TargetSystem.m_XDirection)
|
{
|
target.m_Width= m_TargetSystem.m_Width= m_SrcSystem.m_Width;
|
target.m_Height= m_TargetSystem.m_Height= m_SrcSystem.m_Height;
|
}else
|
{
|
target.m_Width= m_TargetSystem.m_Width= m_SrcSystem.m_Height;
|
target.m_Height= m_TargetSystem.m_Height= m_SrcSystem.m_Width;
|
}
|
|
return IsNeedeToTrans();
|
}
|
void TransToTarget(TTT x, TTT y, TTT &tx, TTT &ty)
|
{
|
// Ãà ¹æÇâ Àüȯ.(¹«º¯È, x2= width- x, y2= height- y)
|
x= x*a+ width;
|
y= y*b+ height;
|
|
// Ãà°£ Àüȯ. (¹«º¯È, x <-> y)
|
if(m_SrcSystem.m_XDirection == m_TargetSystem.m_XDirection)
|
{
|
tx= x;
|
ty= y;
|
}else
|
{
|
tx= y;
|
ty= x;
|
}
|
}
|
void RotateToTarget(TTT x, TTT y, TTT &tx, TTT &ty)
|
{
|
// Ãà ¹æÇâ Àüȯ.(¹«º¯È, x2= width- x, y2= height- y)
|
x= x*a;
|
y= y*b;
|
|
// Ãà°£ Àüȯ. (¹«º¯È, x <-> y)
|
if(m_SrcSystem.m_XDirection == m_TargetSystem.m_XDirection)
|
{
|
tx= x;
|
ty= y;
|
}else
|
{
|
tx= y;
|
ty= x;
|
}
|
}
|
// 1 or -1, theta°ªÀÇ ºÎÈ£¸¦ °áÁ¤ÇÑ´Ù.
|
int GetThetaSign()
|
{
|
int srcDir= thetasign[m_SrcSystem.m_OriginPos][m_SrcSystem.m_XDirection];
|
int tarDir= thetasign[m_TargetSystem.m_OriginPos][m_TargetSystem.m_XDirection];
|
return srcDir*tarDir;
|
}
|
};
|
|
|
// ¾ó¶óÀÎ ¸¶Å©¸¦ ÀÌ¿ëÇÑ ÁÂÇ¥ º¸Á¤.
|
// µÎ°³ÀÇ ¾ó¶óÀÎ ¸¶Å©Áß ÇѰ³ÀÇ ¾ó¶óÀÎ ¸¶Å©¸¦ ±âÁØÁ¡À¸·Î theta »ç¿ë.
|
// Á¤º¸ : ¾ó¶óÀθ¶Å©(¾ó¶óÀÎ ±âÁØÁ¡)ÀÇ x, y, dx, dy(shiftÀ§Ä¡), theta(Ʋ¾îÁø °¢)
|
// ¾ó¶óÀÎ ¸¶Å©±âÁØ¿¡ ÀÇÇÑ º¸Á¤°ú, ¿øÁ¡º¸Á¤À» ÅëÇÑ º¸Á¤ µÎ°¡Áö ¹æ¹ý »ç¿ë °¡´É.
|
// 1. SetAlignData
|
// 2. If Istilted(), then Correct()..
|
|
struct stAlignPoint
|
{
|
int x, y;
|
stAlignPoint() {ResetPoint();}
|
void ResetPoint() {x= -1; y= -1;}// À½¼ö¸¦ °¡Áú ¼ö ¾ø´Ù.
|
BOOL IsPointSet() {return x != -1 && y!= -1;}
|
void SetPoint(int xx, int yy) {x= xx; y= yy;}
|
|
stAlignPoint operator +(stAlignPoint& pt)
|
{
|
stAlignPoint npt;
|
npt.x= x+ pt.x;
|
npt.y= y+ pt.y;
|
return npt;
|
}
|
stAlignPoint operator -(stAlignPoint& pt)
|
{
|
stAlignPoint npt;
|
npt.x= x- pt.x;
|
npt.y= y- pt.y;
|
return npt;
|
}
|
void Scale(double rx, double ry)
|
{
|
x= (int)(x*rx);
|
y= (int)(y*ry);
|
}
|
stAlignPoint operator-()
|
{
|
stAlignPoint pt;
|
pt.x= -x;
|
pt.y= -y;
|
return pt;
|
}
|
};
|
|
struct stAlignInfo
|
{
|
BOOL m_bAlignFound;
|
|
int m_xAlign, m_yAlign; // Align Position(x, y)
|
int m_dxAlign, m_dyAlign; // Align Shift.
|
double m_Theta; // Angle of Glass Tilt == Align Tilt.
|
double m_BasicTheta;
|
double m_ExtraTheta;
|
|
public:
|
void ResetAlignInfo() {m_bAlignFound= FALSE; m_Theta= 0; m_dxAlign= 0; m_dyAlign= 0; m_xAlign= m_yAlign= 0;}
|
|
void SetAlignFound() {m_bAlignFound= TRUE;}
|
BOOL IsAlignFound() {return m_bAlignFound;}
|
|
BOOL IsTilted() {return m_Theta != 0 || m_dxAlign != 0 || m_dyAlign != 0;}
|
|
public:
|
stAlignInfo& SelfAlignInfo() {return *this;}
|
};
|
|
|
|
|
class AFX_EXT_CLASS CAlignFind
|
{
|
public:
|
|
// 1. ±Û¶ó½º »ó¿¡¼ÀÇ ¾ó¶óÀθ¶Å© À§Ä¡¿Í Á¤º¸.
|
CCoordSystem<int> m_csOperator; // ±âÁØ ÁÂÇ¥°è (OP_LEFT_TOP, XD_HORIZONTAL : ÀÛ¾÷ÀÚ ½Ã°¢, ºÒº¯), SetAlignInGlass ¿¡¼ ¼³Á¤µÈ´Ù.
|
|
stAlignPoint m_FirstInGlass; // um ´ÜÀ§
|
stAlignPoint m_SecondInGlass; // um ´ÜÀ§
|
stAlignPoint m_FirstFindInGlass;
|
stAlignPoint m_SecondFindInGlass;
|
|
double m_BasicTheta; // ¼³Á¤ ¾ó¶óÀÎ ¸¶Å© À§Ä¡°¡ °¡Áø °íÀ¯ tilt
|
double m_ExtraTheta;
|
double m_TotalTheta;
|
stAlignPoint m_AlignShift;
|
stAlignPoint m_AlignDelta;
|
|
|
// 2. debugÀ» À§Çؼ ÀúÀ常 ÇØµÐ´Ù. Ä«¸Þ¶ó¿¡¼ÀÇ ¸¶Å© Á¤º¸. ¿ÜºÎ¿¡¼ ¼³Á¤µÇ´Â ÀԷ°ªµéÀÌ´Ù.
|
protected:
|
stAlignPoint m_FirstAlign; // ±âÁØ ¾ó¶óÀÎ ¸¶Å© À§Ä¡. um ´ÜÀ§
|
stAlignPoint m_FirstFind; // ±âÁØ ¾ó¶óÀÎ ¸¶Å© ãÀº °÷. um ´ÜÀ§
|
CCoordSystem<int> m_csFirst;
|
|
stAlignPoint m_SecondAlign; // º¸Á¶ ¾ó¶óÀÎ ¸¶Å© À§Ä¡. um ´ÜÀ§
|
stAlignPoint m_SecondFind; // º¸Á¶ ¾ó¶óÀÎ ¸¶Å© ãÀº °÷. um ´ÜÀ§
|
CCoordSystem<int> m_csSecond;
|
|
|
// 3. debugÀ» À§Çؼ ÀúÀ常 ÇØµÐ´Ù. ±Û¶ó½º »ó ¾ó¶óÀÎ ¸¶Å©ÀÇ À§Ä¡¿Í ÁÂÇ¥.
|
protected:
|
int m_Dx, m_Dy; // ±Û¶ó½º ³¡¿¡¼ ¾ó¶óÀÎ ¸¶Å© ±îÁöÀÇ °Å¸®..
|
OriginPos m_FirstPos; // ¾ó¶óÀÎ ¸¶Å© À§Ä¡.
|
OriginPos m_SecondPos; // ¾ó¶óÀÎ ¸¶Å© À§Ä¡.
|
public:
|
int m_GlassWidth, m_GlassHeight;// ±Û¶ó½º Å©±â.
|
|
|
public:
|
CAlignFind();
|
CCoordSystem<int> GetOperatorCoordSystem(){return m_csOperator;}
|
void ResetAlignFind() { m_FirstFindInGlass.ResetPoint(); m_SecondFindInGlass.ResetPoint();}
|
BOOL IsAlignFound() { return m_FirstFindInGlass.IsPointSet() && m_SecondFindInGlass.IsPointSet();}
|
|
|
// 1. °Å¸® Á¤º¸·Î ±Û¶ó½º ¾ó¶óÀθ¶Å© À§Ã³ ±¸Çϱâ, ±Û¶ó½º ³¡´Ü(left, top)¿¡¼ÀÇ ¾ó¶óÀθ¶Å© °Å¸® dx, dy¿Í glass Width, height¸¦ °¡Áö°í °¢ ¾ó¶óÀθ¶Å© À§Ä¡ ÁÂÇ¥ ±¸Çϱâ.
|
void FillPos(int &x, int &y, OriginPos pos, int dx, int dy, int glassWidth, int glassHeight);
|
public:
|
// 2. ±Û¶ó½ºÀÇ ¾ó¶óÀθ¶Å© Á¤º¸ ¼³Á¤. ´ÜÀ§ um, ÀÛ¾÷ÀÚ ¹æÇâ¿¡¼ÀÇ left, topÀ» ¿øÁ¡À¸·Î xDirectionÀº HorizontalÀ» ±âÁØÀ¸·Î ÇÏ´Â µ¥ÀÌÅÍ´Ù.
|
void SetAlignInGlass(int dx, int dy, int glassWidth, int glassHeight, OriginPos firstPos, OriginPos secondPos, double basicTheta);
|
|
// 3. ¾ó¶óÀθ¶Å© Á¤º¸ ¼³Á¤.. ´ÜÀ§ um, Ä«¸Þ¶ó¿¡¼ÀÇ À§Ä¡¿Í ÁÂÇ¥°èÁ¤º¸.
|
void SetFirstAlign(stAlignPoint first, stAlignPoint find, double rx, double ry, CCoordSystem<int> cameraCoord);
|
void SetSecondAlign(stAlignPoint second, stAlignPoint find, double rx, double ry, CCoordSystem<int> cameraCoord);
|
|
|
// 4. ¾ó¶óÀÎ º¸Á¤°ª ±¸Çϱâ.
|
BOOL CalcAlignInfo(CCoordSystem<int> &targetCoord, stAlignInfo &alignInfo);// operatorÁÂÇ¥°è·Î ¼³Á¤µÈ ¾ó¶óÀθ¶Å©·Î theta°è»êÈÄ targetCoordÁÂÇ¥°è·Î °ªÀ» ȯ»êÇØ ÁØ´Ù.
|
double CalcAlignTheta_Operator(stAlignPoint delta, OriginPos opSrc, XDirection xdSrc);// operatorÁÂÇ¥°è¿¡¼ÀÇ theta°ª ¸®ÅÏ.
|
double CalcAlignTheta_Operator(stAlignPoint a1, stAlignPoint a2, OriginPos opSrc, XDirection xdSrc)
|
{
|
return CalcAlignTheta_Operator(a2- a1, opSrc, xdSrc);
|
}
|
};
|
|
|
// ¾ó¶óÀÎ ¸¶Å©ÀÇ shift¿Í theta ¸¦ ÀÌ¿ëÇØ ÁÂÇ¥ °è»êÇϱâ.
|
// ¾ó¶óÀθ¶Å©ÀÇ shift¸¦ ÀÌ¿ëÇØ ¿øÁ¡ÀÇ shift·®À» °è»êÇÑ´Ù. theta´Â µ¿ÀÏ. SetAlignData
|
// ¿øÁ¡¿¡¼ÀÇ tilt(shift, theta)¸¦ ÀÌ¿ëÇØ ÀÓÀÇ ÁÂÇ¥ÀÇ tiltµÈ ÁÂÇ¥¸¦ °è»êÇØ³½´Ù.
|
// ÁÂÇ¥´Â umÀ» ±âº» ´ÜÀ§·Î »ç¿ëÇÑ´Ù.
|
class AFX_EXT_CLASS CBaseAligning : public stAlignInfo
|
{
|
protected:
|
// AlignData¿¡¼ 2Â÷ °¡°øµÇ´Â Á¤º¸.
|
double m_dCosine; // Cosine(Theta)
|
double m_dSine; // Sine(Theta)
|
double m_dTangent;
|
|
double m_dCosineBack; // Cosine(Theta)
|
double m_dSineBack; // Sine(Theta)
|
|
int m_dxOrigin, m_dyOrigin; // Shift of Glass Original Position
|
|
public:
|
CBaseAligning();
|
|
|
void SetAlignInfo(stAlignInfo &alignData);
|
void SetAlignInfo(double theta, int xAlign, int yAlign, int dxAlign, int dyAlign);
|
|
void Correct_00(int x, int y, int &xPrime, int &yPrime); // ÁÂÇ¥ ±âÁØÀ» ¾ó¶óÀθ¶Å© ±âÁØÀÌ ¾Æ´Ï¶ó ¿øÁ¡±âÁØÀ¸·Î º¯È¯ - ¿¬»ê°³¼ö°¡ ÁØ´Ù.
|
void Correct_00(int &x, int &y) {Correct_00(x, y, x, y);}
|
|
void Correct(int x, int y, int &xPrime, int &yPrime, int bForwardScan, int nGlassHeight); // x, y¸¦ ¾ó¶óÀθ¶Å© ±âÁØÀ¸·Î ÁÂÇ¥º¯È¯ÈÄ Æ¿Æ® º¸Á¤ ¹× ±Û¶ó½º ÁÂÇ¥°è·Î º¹¿ø.
|
void Correct(int &x, int &y, int bForwardScan, int nGlassHeigh) {Correct(x, y, x, y, bForwardScan, nGlassHeigh);}
|
};
|
|
|
|
|
// When use it(Correct_Scan()), first check if belows are called
|
// 1. Reset(), 2. SetAlignData(), 3. SetScanData() 4. IsTilted()
|
class AFX_EXT_CLASS CScanAligning : public CBaseAligning
|
{
|
public:
|
double m_xResolution; // Resolution of X Axis ( Inspector cam)
|
double m_yResolution; // Resolution of Y Axis ( Inspector cam)
|
double m_xAccum; // UM of Cam's Left First Pixel (Left Margin)
|
double m_xAccumOrigin; // UM of Cam's Left Pixel (0)
|
double m_yAccum; // UM of Cam's Left First Pixel (Left Margin)
|
double m_yAccumOrigin; // UM of Cam's Left Pixel (0)
|
int m_LeftMargin; // Left Margin of Each Cam.
|
BOOL m_bForwardScan;
|
|
int m_GlassHeight; // Length of Glass Height
|
int m_TopMargin; // Top Margin of Each Cam.
|
public:
|
void SetScanData(double xResolution, double yResolution, double xAccum, double yAccum, int leftMargin, int glassHeight, int glassStartLine, BOOL bForward);
|
void Correct_Pixel2UM(int x, int y, int &xPrime, int &yPrime);
|
void Correct_Pixel2Pixel(int x, int y, int &xPrime, int &yPrime);
|
void CorrectBack_Pixel2UM(int x, int y, int &xPrime, int &yPrime);
|
void CorrectBack_Pixel2Pixel(int x, int y, int &xPrime, int &yPrime);
|
|
int GetDx_Pixel(int x, int y);
|
int GetDy_Pixel(int x, int y);
|
|
};
|
|
// CCoordTrans ¿ë·Ê. ÁÂÇ¥°è º¯È¯¿¡ µû¸¥ ÁÂÇ¥ º¯È¯ ¿¹.
|
void Example_CoordTrans();
|
|
// ½ºÄµ¿¡¼ ±Û¶ó½º·Î ÁÂÇ¥ º¯È¯°ªÀÌ ¿Ã¹Ù¸¥Áö Å×½ºÆ®Çغ¸ÀÚ.
|
void Test_MakeScanAlignData(CScanAligning &alining);
|
|
#endif // !defined(AFX_GLASSALIGN_H__A4EDE408_69C7_440F_9842_CCDFAA98048A__INCLUDED_)
|