📄 smithchart.c
字号:
/*------------------------------------------------------------------------------*
* File Name: SmithChart.c *
* Creation: JCG 01-23-2002 *
* Purpose: OriginC Source C file *
* Copyright (c) OriginLab Corp. 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 *
* All Rights Reserved *
* *
* Modification Log: *
* JCG 12/06/02 QA70-1474 SEMI_COLON_MISSED *
*------------------------------------------------------------------------------*/
#include <origin.h>
//this header file contains string const that can be localized into different languages
// the '$' is placed in front of the file name to indicate that it might have a localization version
// located in the \Localization folder of the Origin installation
#include "$local.h"
//Function: void SmithChartRX2UV( double rr, double xx, double& uu, double& vv )
void SmithChartRX2UV( double rr, double xx, double& uu, double& vv )
{
uu = ( rr^2 - 1 + xx^2 ) / ( ( rr + 1 )^2 + xx^2 );
vv = 2 * xx / ( ( rr + 1 )^2 + xx^2 );
}
//Function: void SmithChartRX2UV( double uu, double vv, double& rr, double& rr )
void SmithChartUV2RX( double uu, double vv, double& rr, double& xx )
{
rr = ( 1 - uu^2 - vv^2 ) / ( (1 - uu )^2 + vv^2 );
xx = 2 * vv / ( ( 1 - uu )^2 + vv^2 );
}
//Function: BOOL SmithChartSetParameters()
BOOL SmithChartSetParameters()
{
if ( !IsSmithChartCoordinate() )
return FALSE;
double divideby;
if( !LT_get_var( "layer.y.label.divideby",÷by ) )
return FALSE;
string strRtip;
strRtip.Format("%4.1f", 1 / divideby);
if( !LT_set_str( "SmithChart!Rtip$", strRtip) )
return FALSE;
if( !LT_set_str( "SmithChart!NormFactor$", strRtip) )
return FALSE;
if( !LT_set_var( "SmithChart!Redit.v1", 1 / divideby * 1.2 ) ) //Make sure the R edit is larger that R tip.
return FALSE;
return TRUE;
}
//Funciton: BOOL SmithChartNomalize( string strNormEdit )
BOOL SmithChartNomalize( string strNormEdit )
{
if ( !IsSmithChartCoordinate() )
return FALSE;
if ( !strNormEdit.IsEmpty() ) //Not empty
{
double factor;
if ( !LT_evaluate( strNormEdit , &factor ) ) //Need evaluate the value for given string
return FALSE;
if ( 0.0 == factor )
{
string strPromptZero = SM_FACTOR_EVAL_AS_ZERO;
MessageBox( NULL, strPromptZero );
return FALSE;
}
//Here test the norm edit string, if = 1 set as 1, if 33.3 set as 3/100 else set as 1/string.
if( !strNormEdit.Compare("1"))
; //Null
else
if( !strNormEdit.Compare("33.3"))
strNormEdit = "3/100";
else
strNormEdit = "1/" + strNormEdit;
//Set divideby string.
if( !LT_set_str( "layer.x.label.divideby$", strNormEdit ) ) //For consistency with plot detail dialog box
return FALSE;
if( !LT_set_str( "layer.y.label.divideby$", strNormEdit ) ) //For consistency with plot detail dialog box
return FALSE;
if( is_equal( round( factor, 3 ), round( 1.0, 3 ) ) )
{
if( !LT_set_var( "layer.x.decPlaces", 1 ) )
return FALSE;
if( !LT_set_var( "layer.y.decPlaces", 1 ) )
return FALSE;
}
else
{
if( !LT_set_var( "layer.x.decPlaces", 0 ) )
return FALSE;
if( !LT_set_var( "layer.y.decPlaces", 0 ) )
return FALSE;
}
double divideby;
if( !LT_get_var( "layer.y.label.divideby",÷by ) )
return FALSE;
if( !LT_set_var( "SmithChart!Redit.v1", 1 / divideby * 1.2 ) ) //Make sure the R edit is larger that R tip.
return FALSE;
if( !LT_set_str( "SmithChart!Rtip$", strNormEdit ) )
return FALSE;
return TRUE;
}
else
{
string strPromptEmpty = SM_FACTOR_NOT_EMPTY;
MessageBox( NULL, strPromptEmpty );
}
return FALSE;
}
//Function: BOOL SmithChartReverse( )
BOOL SmithChartReverse( )
{
if ( !IsSmithChartCoordinate() )
return FALSE;
double reverse;
if( !LT_get_var( "layer.x.reverse",&reverse ) )
return FALSE;
if ( reverse == 1 )
{
if( !LT_set_var( "layer.x.reverse", 0 ) )
return FALSE;
}
else
{
if( !LT_set_var( "layer.x.reverse", 1 ) )
return FALSE;
}
return TRUE;
}
//Function: BOOL SmithChartConvert(string strCurve, UINT opt)
// Arg: if opt = CONVERT_DATA_TO_MAGANG, convert current data to R+jX format
// if opt = REINTERPRET_DATA_AS_MAGANG, caculate the MAG/ANG data from R and X value
enum{ CONVERT_DATA_TO_MAGANG = 0, REINTERPRET_DATA_AS_MAGANG };
BOOL SmithChartConvert(string strCurve, UINT nOpt)
{
if ( !IsSmithChartCoordinate() )
return FALSE;
if ( !SmithChartCheckCurveName( strCurve ) )
return FALSE;
Curve cc(strCurve);
string strYdataName;
if(!cc.GetName(strYdataName))
return FALSE;
Dataset xData;
if(!cc.AttachX(xData))
return FALSE;
string strWksName;
string strColName;
int nUnderScorePos = strYdataName.Find( '_' );
if ( -1 == nUnderScorePos || 0 == nUnderScorePos )
return FALSE;
strWksName = strYdataName.Left( nUnderScorePos );
strColName = strYdataName.Right( strYdataName.GetLength() - nUnderScorePos - 1 );
Worksheet wks(strWksName);
int nYDataColNum = wks.Columns(strColName).GetIndex();
string strMagCol, strAngCol;
strMagCol = "Mag";
strAngCol = "Angle";
if( !wks.InsertCol(nYDataColNum + 1, strMagCol, strMagCol ) )
return FALSE;
if ( !wks.Columns( nYDataColNum + 1 ).SetType(OKDATAOBJ_DESIGNATION_X ) )
return FALSE;
if( !wks.InsertCol(nYDataColNum + 2, strAngCol, strAngCol ) )
return FALSE;
if ( !wks.Columns( nYDataColNum + 2).SetType(OKDATAOBJ_DESIGNATION_Y ) )
return FALSE;
UINT nRows = xData.GetUpperBound() + 1;
double rr, xx, uu,vv;
Dataset mag( strWksName,nYDataColNum + 1);
Dataset angle( strWksName,nYDataColNum + 2 );
mag.SetSize(nRows);
angle.SetSize(nRows);
// assume we are working on current graph layer
double divideby;
if(!LT_get_var("layer.y.label.divideby",÷by))
return FALSE;
UINT ii;
if( nOpt == CONVERT_DATA_TO_MAGANG )
{
for ( ii = xData.GetLowerBound(); ii < nRows; ii++ )
{
rr = xData[ii];
xx = cc[ii];
// rr can not be -1 and at the same time xx equal 0
if( -1 != rr && 0 != xx )
{
SmithChartRX2UV( rr, xx, uu, vv );
mag[ii] = sqrt( ( uu^2 + vv^2 ) ) / divideby;
if(0 != uu )
angle[ii] = atan( vv / uu ) * 180 / PI;
else
{
if(0 != vv )
angle[ii] = 90;
else
angle[ii] = 0;
}
}
else
{
mag[ii] = 0; //-1 maybe the negative plot
angle[ii] = 0;
}
}
}
if( nOpt == REINTERPRET_DATA_AS_MAGANG )
{
//First backup the original data
for ( ii = xData.GetLowerBound(); ii < nRows; ii++ )
{
mag[ii] = xData[ii];
angle[ii] = cc[ii];
}
//The mag must bein the range of -1 and 1
//and the angle is in the unit of degree.
//After the conversion the norlization values are set as 1
for ( ii = xData.GetLowerBound(); ii < nRows; ii++ )
{
uu = mag[ii] * cos ( angle[ii] * PI / 180 );
vv = mag[ii] * sin ( angle[ii] * PI / 180 );
//uu can not be 1 and at the same time vv equal 0
if( 1 == uu && 0 == vv )
{
xData[ii] = 0;
cc[ii] = 1;
}
else
{
SmithChartUV2RX( uu, vv, xData[ii], cc[ii] );
}
}
//At last the divideby must set as 1;
if( !LT_set_str( "layer.x.label.divideby$","1" ) )
return FALSE;
if( !LT_set_str( "layer.y.label.divideby$","1" ) )
return FALSE;
//Also shold set the decimal places at 1;
if( !LT_set_var( "layer.x.decPlaces", 1 ) )
return FALSE;
if( !LT_set_var( "layer.y.decPlaces", 1 ) )
return FALSE;
}
string strActivate = "win -a ";
strActivate += strWksName;
LT_execute(strActivate, 0);
return TRUE;
}
BOOL SmithChartSWR( string strCurve, double ptR, double ptX )
{
if ( !IsSmithChartCoordinate() )
return FALSE;
string strWksSWRName = "SWRData";
Worksheet wks( strWksSWRName );
if ( !wks.IsValid() )
{
if ( !wks.Create( NULL , CREATE_HIDDEN) ) //If SWRData is not exist create a new one
return FALSE;
Page pp;;
pp = wks.GetPage();
if ( !pp.Rename( strWksSWRName ) ) // Rename the new one as SWRData
return FALSE;
//ASSERT( 2 == wks.GetNumCols() ) //2 cols by default.
ASSERT( 2 == wks.GetNumCols() ); //2 cols by default. ///JCG 12/06/02 QA70-1474 SEMI_COLON_MISSED
while( wks.DeleteCol(0) );
ASSERT( 0 == wks.GetNumCols() );
}
double divideby;
if( !LT_get_var( "layer.y.label.divideby",÷by ) )
return FALSE;
if( ptR <= 1 / divideby )
{
string strRtip;
strRtip.Format("%4.1f", 1 / divideby);
string strPrompt = SM_RVAL_LARGER_THAN + strRtip;
MessageBox( NULL, strPrompt );
return TRUE;
}
ptR *= divideby;
ptX *= divideby;
double uu,vv, mag;
SmithChartRX2UV( ptR, ptX, uu, vv );
mag = sqrt( ( uu^2 + vv^2 ) );
string strRadius;
strRadius.Format("%4.2f", mag );
string strSWRRCol, strSWRXCol;
strSWRRCol = "SWRR" + strRadius;
strSWRXCol = "SWRX" + strRadius;
if( wks.Columns( strSWRRCol) == NULL )
{
if ( wks.AddCol( strSWRRCol, strSWRRCol ) < 0 )
return FALSE;
}
if ( !wks.Columns( strSWRRCol).SetType(OKDATAOBJ_DESIGNATION_X ) ) //Set column type as X i.e. R for smith chart
return FALSE;
if( wks.Columns( strSWRXCol) == NULL )
{
if ( wks.AddCol( strSWRXCol, strSWRXCol ) < 0 )
return FALSE;
}
if ( !wks.Columns( strSWRXCol).SetType(OKDATAOBJ_DESIGNATION_Y ) ) //Set column type as Y i.e. X for smith chart
return FALSE;
if( !wks.Columns( strSWRRCol).SetWidth( strSWRRCol.GetLength() + 4 ) ) // 4 is for the width of "(X2)"
return FALSE;
if( !wks.Columns( strSWRXCol).SetWidth( strSWRXCol.GetLength() + 4 ) ) // 4 is for the width of "(X2)"
return FALSE;
Dataset SWRR( strWksSWRName, wks.Columns(strSWRRCol).GetIndex() );
Dataset SWRX( strWksSWRName, wks.Columns(strSWRXCol).GetIndex() );
double dbPointDensity;
if( !LT_get_var( "SmithChart!PointDensity",&dbPointDensity ) )
return FALSE;
double angleStep = ( 4 - dbPointDensity ) / mag / 5; // 1 degree for High, 2 degree for Medium, 3 degree for low
int nPts = 360 / angleStep;
angleStep *= PI / 180;
if ( nPts > wks.GetNumRows() ) // Append rows if not enough
{
if( !wks.AppendRows( nPts - wks.GetNumRows() ) )
return FALSE;
}
SWRR.SetSize( nPts + 1 ); //Allocate memory here and Make sure the cirlce is closed
SWRX.SetSize( nPts + 1);
for( UINT ii = 0; ii < nPts; ii++ )
{
uu = mag * cos ( ii * angleStep );
vv = mag * sin ( ii * angleStep );
if( 1 == uu && 0 == vv )
{
SWRR[ii] = 0;
SWRX[ii] = 1 / divideby; // Use current user selected normalize value
}
else
{
SmithChartUV2RX( uu, vv, SWRR[ii], SWRX[ii] );
SWRR[ii] /= divideby; // Use current user selected normalize value
SWRX[ii] /= divideby; // Use current user selected normalize value
}
}
SWRR[ nPts ] = SWRR[0];
SWRX[ nPts ] = SWRX[0];
char szGraphName[20];
if( !LT_get_str( "%H", szGraphName, 20 ) ) // Get current graph name by labtalk
return FALSE;
Curve ccswr( strWksSWRName + "_" + strSWRRCol, strWksSWRName + "_" + strSWRXCol);
if ( ccswr.IsValid() )
{
GraphLayer graph( szGraphName );
int nCurveColor = 1;// need to get from DDK, 1=Black, 2 = Red, 3 = Blue
int nPlot = graph.AddPlot( ccswr, IDM_PLOT_LINE );
if ( nPlot < 0 ) // plot SWR data
return FALSE;
double dbColorIndex;
if( !LT_get_var( "SmithChart!CircleColor",&dbColorIndex ) )
return FALSE;
nCurveColor = dbColorIndex;
switch(nCurveColor)
{
case 1:
graph.DataPlots(nPlot).SetColorRGB(0,0,0);
break;
case 2: // Red
graph.DataPlots(nPlot).SetColorRGB(255,0,0);
break;
case 3: // Blue
graph.DataPlots(nPlot).SetColorRGB(0,0,255);
break;
}
}
return TRUE;
}
//Function: BOOL IsSmithChartCoordinate()
BOOL IsSmithChartCoordinate()
{
char szGraphName[20];
if( !LT_get_str( "%H", szGraphName, 20 ) ) // Get current graph name by labtalk
return FALSE;
GraphLayer graph( szGraphName );
if(graph)
{
UINT nCoorType = graph.GetCoordinateType();
if ( FRAME_COOR_SMITH_CHART == nCoorType )
return TRUE;
}
return FALSE;
}
BOOL SmithChartCheckCurveName( string strCurveName )
{
if( strCurveName.IsEmpty() )
{
string strPrompt = SM_NO_CURVE;
MessageBox( NULL, strPrompt );
return FALSE;
}
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -