/********************************************************************************** * AUTHOR : Mehul Patel * DATE : 29-MAR-2005 * NAME : computePII * DESCRIPTION : Computes the Position Information Index * ARGUMENTS : inTrace - the trace for which TCL is to be calculated * RETURNS : PII - Position Information Index * NOTES : * CHANGE HISTROY * Author Date Description of change *************************************************************************************/ float HolisticFeatureExtractor::computePII(const LTKTrace& inTrace, const LTKScreenContext screenContext) { int pointIndex; // Index to loop over all the points int numOfPoints; // total number of points in the trace float PII=0.0f; // Position Information Index float bboxTop = screenContext.getBboxTop(); float bboxBottom = screenContext.getBboxBottom(); float vThresh = (bboxTop + bboxBottom)/2; // vertical threshold floatVector yData; // y-coordinates of the points in the trace yData = inTrace.getChannelValues("Y"); numOfPoints = yData.size(); for(pointIndex = 0; pointIndex < numOfPoints; ++pointIndex) { if(yData.at(pointIndex)>vThresh) { ++PII; } } PII /= numOfPoints; return PII; }
float HolisticFeatureExtractor::computeOrientation(const LTKTrace& inTrace) { int numOfPoints; // total number of points in the trace float orient = 0.0f; // orientation floatVector xData, yData; // coordinates of the points in the trace xData = inTrace.getChannelValues("X"); yData = inTrace.getChannelValues("Y"); numOfPoints = xData.size(); orient = calculateSlope(xData.at(0),yData.at(0),xData.at(numOfPoints-1),yData.at(numOfPoints-1)); // convert all angles to a range 0 to pi if (orient<0) { orient += PI; } // normalizing it from 0 to 1 orient /= PI; // make horizontal stroke as 180 degrees instead of 2 values if (orient<(m_horizStrokeAngleThresh/180)) { orient = 1 - orient; } return orient; }
float HolisticFeatureExtractor::computeEER(const LTKTrace& inTrace) { int numOfPoints; // total number of points in the trace float EEL = 0.0f; // End-to-end Length float TCL = 0.0f; // Total Curve Length float EER = 0.0f; // End-to-end Ratio floatVector xData, yData; // coordinates of the points in the trace xData = inTrace.getChannelValues("X"); yData = inTrace.getChannelValues("Y"); numOfPoints = xData.size(); EEL = calculateEuclidDist(xData.at(0),yData.at(0),xData.at(numOfPoints-1),yData.at(numOfPoints-1)); TCL = computeTCL(inTrace); EER = EEL/TCL; return EER; }
float HolisticFeatureExtractor::computeTCL(const LTKTrace& inTrace) { float TCL=0.0f; // Total Curve Length int pointIndex; // Index to loop over all the points floatVector xData, yData; // coordinates of the points in the trace xData = inTrace.getChannelValues("X"); yData = inTrace.getChannelValues("Y"); for(pointIndex = 0; pointIndex < xData.size()-1; ++pointIndex) { TCL += calculateEuclidDist(xData.at(pointIndex),yData.at(pointIndex),xData.at(pointIndex+1),yData.at(pointIndex+1)); } return TCL; }
/********************************************************************************** * AUTHOR : Deepu V. * DATE : 09-MAR-2005 * NAME : computeChannelStatistics * DESCRIPTION : This is a generic function that computes the statistics of channels of * an LTKTraceGroup object passed to it. * ARGUMENTS : traceGroup - The TraceGroup whose statistics need to be computed channelNames - Names of channels in the traceGroup for which * channelNames - channels for which statistics have to be comptued * properties - The names of the statistics to be computed * channelStatistics - output vector containing results * channelStatistics[i][j] the statistics properties[j] for channelname * channelNames[i] * * RETURNS : SUCCESS/FAILURE * NOTES : * CHANGE HISTROY * Author Date Description of change *************************************************************************************/ int LTKInkUtils::computeChannelStatistics(const LTKTraceGroup& traceGroup, const vector<string>& channelNames, const vector<ELTKTraceGroupStatistics>& properties, vector<vector<float> >& channelStatistics) { LOG( LTKLogger::LTK_LOGLEVEL_DEBUG) << " Entering: LTKInkUtils::computeChannelStatistics()" << endl; vector<float> tempVec; //temporary vector int numChannels = channelNames.size(); //num of channels for which statistics need to be computed int numFeatures = properties.size(); //number of properties to be calculated int numTraces = traceGroup.getNumTraces(); //number of traces in each tracegroup int numPoints; //number of points in a stroke int totalNumPoints=0; //each channel is of equal length float currVal; //value of current point in the channel int traceIndex, channelIndex, pointIndex, featureIndex; // Clear the output vector channelStatistics.clear(); //Make an initial vector tempVec.clear(); for (featureIndex= 0 ; featureIndex <numFeatures; ++featureIndex) { switch(properties[featureIndex]) { //initializing max case TG_MAX:tempVec.push_back(-FLT_MAX); break; //initializing min case TG_MIN:tempVec.push_back(FLT_MAX); break; //initializing avg case TG_AVG:tempVec.push_back(0); break; default: LOG(LTKLogger::LTK_LOGLEVEL_ERR) <<"Error: LTKInkUtils::computeChannelStatistics()"<<endl; LTKReturnError(EUNSUPPORTED_STATISTICS); } } //Initialization Every channel has the same value for(channelIndex =0; channelIndex<numChannels; ++channelIndex) { channelStatistics.push_back(tempVec); //initialize total number of points for each channel to zero } //Iterating through all the strokes for (traceIndex = 0; traceIndex <numTraces; ++traceIndex) { LTKTrace trace; traceGroup.getTraceAt(traceIndex, trace); //Iterating through all the channels in a stroke for (channelIndex =0; channelIndex<numChannels; ++channelIndex) { //get the current channel values floatVector currChannel; trace.getChannelValues(channelNames[channelIndex], currChannel); //get the current output vector to be updated floatVector& currStats = channelStatistics.at(channelIndex); //number of points in this channel numPoints = currChannel.size(); if(channelIndex==0) { totalNumPoints += numPoints; } //iterate through all points in the channel for(pointIndex = 0; pointIndex <numPoints; ++pointIndex) { currVal = currChannel[pointIndex]; //updating all features as we iterate through each point; for (featureIndex =0; featureIndex<numFeatures; featureIndex++) { switch(properties[featureIndex]) { //updating the maximum case TG_MAX: if(currVal > currStats[featureIndex]) currStats[featureIndex] = currVal; break; //updating the minimum case TG_MIN: if(currVal < currStats[featureIndex]) currStats[featureIndex] = currVal; break; //accumulating the sum case TG_AVG: currStats[featureIndex] += currVal; break; default: LOG(LTKLogger::LTK_LOGLEVEL_ERR) <<"Error: LTKInkUtils::computeChannelStatistics()"<<endl; LTKReturnError(EUNSUPPORTED_STATISTICS); } } } } } //Finalization Step for (channelIndex= 0 ; channelIndex<numChannels; ++channelIndex) { floatVector& currStats = channelStatistics.at(channelIndex); //total number of points in this channel numPoints = totalNumPoints; for(featureIndex = 0; featureIndex<numFeatures; ++featureIndex) { switch(properties[featureIndex]) { //finding the average case TG_AVG: currStats[featureIndex] /= numPoints; break; } } } LOG( LTKLogger::LTK_LOGLEVEL_DEBUG) << " Exiting: LTKInkUtils::computeChannelStatistics()" << endl; return SUCCESS; }
float HolisticFeatureExtractor::computeSweptAngle(const LTKTrace& inTrace) { float swAng=0.0f; // Swept Angle int numOfPoints; // total number of points in the trace int pointIndex; // Index to loop over all the points floatVector angles; // angles made by each line with x-axis floatVector angleDiff; // difference of angles between consecutive lines floatVector xData, yData; // coordinates of the points in the trace xData = inTrace.getChannelValues("X"); yData = inTrace.getChannelValues("Y"); numOfPoints = xData.size(); for(pointIndex = 0; pointIndex < numOfPoints-1; ++pointIndex) { float angle; angle = calculateSlope(xData.at(pointIndex),yData.at(pointIndex),xData.at(pointIndex+1),yData.at(pointIndex+1)); // converting the angles from 0 to 360 degrees if (angle < 0) { angle += 2*PI; } angles.push_back(angle); } for(pointIndex = 0; pointIndex < numOfPoints-2; ++pointIndex) { int sign_angle; angleDiff.push_back(angles.at(pointIndex)-angles.at(pointIndex+1)); sign_angle = (angleDiff.at(pointIndex) < 0) ? -1:1; // if greater than 180 then correcting it to a value less than 180 if (fabs(angleDiff.at(pointIndex)) > PI) { angleDiff.at(pointIndex) = -sign_angle * (2*PI - fabs(angleDiff.at(pointIndex))); } // if greater than swAngHookThresh then assuming it to be a hook // and disregarding the angle if (fabs(angleDiff.at(pointIndex)) > (m_swAngHookThresh*PI/180)) { angleDiff.at(pointIndex) = 0; } swAng += angleDiff.at(pointIndex); } // returning the absolute value of swept angle swAng = fabs(swAng); return swAng; }
int HolisticFeatureExtractor::resampleTrace(const LTKTrace& inTrace,int resamplePoints, LTKTrace& outTrace) { LOG( LTKLogger::LTK_LOGLEVEL_DEBUG) << "Entered PCAShapeRecognizer::resampleTrace" << endl; int pointIndex; // a variable to loop over the points of a trace int currentPointIndex =0; // index of the current point float xSum = 0.0f; // sum of the x coordinate values float ySum = 0.0f; // sum of the y coordinate values int numTracePoints; // number of points in a trace int ptIndex = 0; // index of point in a trace float x; // an x coord value float y; // an y coord value float xDiff; // differenc in x direction float yDiff; // diference in y direction float xTemp; // temp x storage float yTemp; // temp y storage float unitLength = 0; // estimated length of each segment after resampling float pointDistance; float balanceDistance = 0; // distance between the last resampled point and // the next raw sample point float measuredDistance; float m1,m2; floatVector xVec; floatVector resampledXVec; floatVector yVec; floatVector resampledYVec; floatVector distanceVec; numTracePoints = inTrace.getNumberOfPoints(); if(numTracePoints == 0) { LOG( LTKLogger::LTK_LOGLEVEL_ERR) << string(getError(EEMPTY_TRACE)) << endl; LTKReturnError(EEMPTY_TRACE); } //xVec = inTrace.getChannelValues(xChannelstr); xVec = inTrace.getChannelValues("X"); //yVec = inTrace.getChannelValues(yChannelstr); yVec = inTrace.getChannelValues("Y"); LOG( LTKLogger::LTK_LOGLEVEL_DEBUG) << "resamplePoints = " , resamplePoints << endl; if(resamplePoints < 1) { resamplePoints = 1; } if(resamplePoints == 1) { xSum=accumulate(xVec.begin(),xVec.end(),0.0f); ySum=accumulate(yVec.begin(),yVec.end(),0.0f); x = xSum/ numTracePoints; //As only 1 point is required, this ratio is computed. y = ySum/ numTracePoints; LOG( LTKLogger::LTK_LOGLEVEL_DEBUG) << "x mean = " << x << endl; LOG( LTKLogger::LTK_LOGLEVEL_DEBUG) << "y mean = " << y << endl; resampledXVec.push_back(x); resampledYVec.push_back(y); outTrace.addChannel(resampledXVec, xChannelstr); outTrace.addChannel(resampledYVec, yChannelstr); } else if(numTracePoints <= 1) { x = xVec.at(0); y = yVec.at(0); for(pointIndex = 0; pointIndex < resamplePoints; ++pointIndex) { resampledXVec.push_back(x); resampledYVec.push_back(y); LOG( LTKLogger::LTK_LOGLEVEL_DEBUG) << "resampled point " << x << y << endl; } outTrace.addChannel(resampledXVec, xChannelstr); outTrace.addChannel(resampledYVec, yChannelstr); } else { LOG( LTKLogger::LTK_LOGLEVEL_DEBUG) << "Point distances" << endl; for( pointIndex = 0; pointIndex < (numTracePoints-1); ++pointIndex) { xDiff = xVec.at(pointIndex) - xVec.at(pointIndex+1); yDiff = yVec.at(pointIndex) - yVec.at(pointIndex+1); pointDistance = (float) (sqrt(xDiff*xDiff + yDiff*yDiff)); //distance between 2 points. unitLength += pointDistance; // finding the length of trace. distanceVec.push_back(pointDistance); //storing distances between every 2 consecutive points. LOG( LTKLogger::LTK_LOGLEVEL_DEBUG) << "point distance: " << pointDistance << endl; } unitLength /= (resamplePoints -1); LOG( LTKLogger::LTK_LOGLEVEL_DEBUG) << "unitLength = " << unitLength << endl; x = xVec.at(0); // adding x of first point; y = yVec.at(0); // adding y of first point; resampledXVec.push_back(x); resampledYVec.push_back(y); LOG( LTKLogger::LTK_LOGLEVEL_DEBUG) << "resampled point " << x << y << endl; for(pointIndex = 1; pointIndex < (resamplePoints-1); ++pointIndex) { measuredDistance = balanceDistance; while(measuredDistance < unitLength) { measuredDistance += distanceVec.at(ptIndex++); if(ptIndex == 1) { currentPointIndex = 1; } else { currentPointIndex++; } } if(ptIndex < 1) ptIndex = 1; m2 = measuredDistance - unitLength; m1 = distanceVec.at(ptIndex -1) - m2; if( fabs(m1+m2) > EPS) { xTemp = (m1* xVec.at(currentPointIndex) + m2* xVec.at(currentPointIndex -1))/(m1+m2); yTemp = (m1* yVec.at(currentPointIndex) + m2* yVec.at(currentPointIndex -1))/(m1+m2); } else { xTemp = xVec.at(currentPointIndex); yTemp = yVec.at(currentPointIndex); } resampledXVec.push_back(xTemp); resampledYVec.push_back(yTemp); LOG( LTKLogger::LTK_LOGLEVEL_DEBUG) << "resampled point " << xTemp << yTemp << endl; balanceDistance = m2; } x = xVec.at(xVec.size() - 1); // adding x of last point; y = yVec.at(yVec.size() - 1); // adding y of last point; resampledXVec.push_back(x); resampledYVec.push_back(y); LOG( LTKLogger::LTK_LOGLEVEL_DEBUG) << "resampled point " << x << y << endl; outTrace.addChannel(resampledXVec, xChannelstr); outTrace.addChannel(resampledYVec, yChannelstr); } LOG( LTKLogger::LTK_LOGLEVEL_DEBUG) << "Exiting PCAShapeRecognizer::resampleTrace" << endl; return SUCCESS; }
/********************************************************************************** * AUTHOR : Bharath A * DATE : 12-Jun-2008 * NAME : extractFeatures * DESCRIPTION : Extracts NPen features from a trace group * ARGUMENTS : The trace group from which features have to be extracted * RETURNS : vector of NPenShapeFeature objects * NOTES : * CHANGE HISTROY * Author Date Description of change *************************************************************************************/ int NPenShapeFeatureExtractor::extractFeatures(const LTKTraceGroup& inTraceGroup, vector<LTKShapeFeaturePtr>& outFeatureVec) { LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Entering " << "NPenShapeFeatureExtractor::extractFeatures()" << endl; NPenShapeFeature* featurePtr = NULL; vector<vector<float> > floatFeatureValues; int errorCode; if(inTraceGroup.getNumTraces() == 0) { LOG(LTKLogger::LTK_LOGLEVEL_ERR) <<"Error: FeatureExtractor::findAllFeatures"<<endl; LTKReturnError(EEMPTY_TRACE_GROUP); } vector<vector<float> > concatenatedCoord; int currPenUpPointIndex = -1; vector<int> penUpPointsIndices; int halfWindowSize = m_windowSize/2; if(halfWindowSize==0) { LOG(LTKLogger::LTK_LOGLEVEL_ERR) <<"Error: FeatureExtractor::findAllFeatures"<<endl; LTKReturnError(EINVALID_NUM_OF_POINTS); } for(int t=0;t<inTraceGroup.getNumTraces();++t) { LTKTrace eachTrace; inTraceGroup.getTraceAt(t,eachTrace); if(eachTrace.isEmpty()) { LOG(LTKLogger::LTK_LOGLEVEL_ERR) <<"Error: FeatureExtractor::findAllFeatures"<<endl; LTKReturnError(EEMPTY_TRACE); } vector<float> xVec; vector<float> yVec; eachTrace.getChannelValues(X_CHANNEL_NAME,xVec); eachTrace.getChannelValues(Y_CHANNEL_NAME,yVec); if(t==0) { vector<float> firstPoint; firstPoint.push_back(xVec[0]); firstPoint.push_back(yVec[0]); concatenatedCoord.insert(concatenatedCoord.begin(),halfWindowSize,firstPoint); } for(int p=0;p<xVec.size();++p) { vector<float> point; point.push_back(xVec[p]); point.push_back(yVec[p]); concatenatedCoord.push_back(point); } currPenUpPointIndex += xVec.size(); penUpPointsIndices.push_back(currPenUpPointIndex); if(t==(inTraceGroup.getNumTraces()-1)) { vector<float> lastPoint; lastPoint.push_back(xVec[xVec.size()-1]); lastPoint.push_back(yVec[yVec.size()-1]); concatenatedCoord.insert(concatenatedCoord.end(),halfWindowSize,lastPoint); } } /* 0 - normalized x 1 - normalized y 2 - cos alpha 3 - sin alpha 4 - cos beta 5 - sin beta 6 - aspect 7 - curliness 8 - linearity 9 - slope 10 - pen-up / pen-down stroke (0 for pen-down and 1 for pen-up)*/ float deltaX=0; float deltaY=0; float hypotenuse=0; float cosalpha=0; float sinalpha=0; float cosbeta=0; float sinbeta=0; float ispenup=0; float aspect=0; float curliness=0; float linearity=0; float slope=0; float xMin,yMin,xMax,yMax; //for vicnity bounding box; float bbWidth,bbHeight; float maxOfWidthHeight; currPenUpPointIndex = 0; for(int f=halfWindowSize;f<(concatenatedCoord.size()-halfWindowSize);++f) { vector<float> eachPointFeature; eachPointFeature.push_back(concatenatedCoord[f][0]); //x eachPointFeature.push_back(concatenatedCoord[f][1]); //y deltaX = concatenatedCoord[f-1][0] - concatenatedCoord[f+1][0]; deltaY = concatenatedCoord[f-1][1] - concatenatedCoord[f+1][1]; hypotenuse = sqrt((deltaX*deltaX)+(deltaY*deltaY)); if(hypotenuse < EPS) { cosalpha = 1; sinalpha = 0; } else { cosalpha = deltaX / hypotenuse; sinalpha = deltaY / hypotenuse; } eachPointFeature.push_back(cosalpha); eachPointFeature.push_back(sinalpha); eachPointFeature.push_back(cosbeta); //creating empty spaces for cosine and sine betas for future assignment eachPointFeature.push_back(sinbeta); vector<vector<float> > vicinity; float vicinityTrajLen = 0.0f; for(int v=f-halfWindowSize;v<=f+halfWindowSize;++v) { vicinity.push_back(concatenatedCoord[v]); if(v<(f+halfWindowSize)) { vicinityTrajLen += (sqrt(((concatenatedCoord[v+1][1]-concatenatedCoord[v][1])*(concatenatedCoord[v+1][1]-concatenatedCoord[v][1]))+((concatenatedCoord[v+1][0]-concatenatedCoord[v][0])*(concatenatedCoord[v+1][0]-concatenatedCoord[v][0])))); } } findVicinityBoundingBox(vicinity,xMin,yMin,xMax,yMax); bbWidth = xMax - xMin; bbHeight = yMax - yMin; if(fabs(bbHeight+bbWidth)<EPS) { aspect = 0.0; } else { aspect = (bbHeight-bbWidth)/(bbHeight+bbWidth); } eachPointFeature.push_back(aspect); maxOfWidthHeight = ( bbWidth > bbHeight) ? bbWidth : bbHeight; if(fabs(maxOfWidthHeight) < EPS) { curliness = 0.0f; } else { curliness = (vicinityTrajLen / maxOfWidthHeight) - 2; } eachPointFeature.push_back(curliness); computeLinearityAndSlope(vicinity,linearity,slope); eachPointFeature.push_back(linearity); eachPointFeature.push_back(slope); if(penUpPointsIndices[currPenUpPointIndex] == (f-halfWindowSize)) { ispenup = 1; ++currPenUpPointIndex; } else { ispenup = 0; } eachPointFeature.push_back(ispenup); //currently assuming pen-up strokes are not resampled floatFeatureValues.push_back(eachPointFeature); } //duplicating first and last features vector<float> firstFeaturePoint = floatFeatureValues[0]; floatFeatureValues.insert(floatFeatureValues.begin(),1,firstFeaturePoint); vector<float> lastFeaturePoint = floatFeatureValues[floatFeatureValues.size()-1]; floatFeatureValues.insert(floatFeatureValues.end(),1,lastFeaturePoint); for(int ff=1;ff<(floatFeatureValues.size()-1);++ff) { floatFeatureValues[ff][4] = (floatFeatureValues[ff-1][2]*floatFeatureValues[ff+1][2]) + (floatFeatureValues[ff-1][3]*floatFeatureValues[ff+1][3]); floatFeatureValues[ff][5] = (floatFeatureValues[ff-1][2]*floatFeatureValues[ff+1][3]) - (floatFeatureValues[ff-1][3]*floatFeatureValues[ff+1][2]); } //removing the extraneous feature points at the beginning and end floatFeatureValues.erase(floatFeatureValues.begin(),floatFeatureValues.begin()+1); floatFeatureValues.pop_back(); for(int a=0;a<floatFeatureValues.size();++a) { NPenShapeFeature* ptrFeature = new NPenShapeFeature(); ptrFeature->setX(floatFeatureValues[a][0]); ptrFeature->setY(floatFeatureValues[a][1]); ptrFeature->setCosAlpha(floatFeatureValues[a][2]); ptrFeature->setSinAlpha(floatFeatureValues[a][3]); ptrFeature->setCosBeta(floatFeatureValues[a][4]); ptrFeature->setSinBeta(floatFeatureValues[a][5]); ptrFeature->setAspect(floatFeatureValues[a][6]); ptrFeature->setCurliness(floatFeatureValues[a][7]); ptrFeature->setLinearity(floatFeatureValues[a][8]); ptrFeature->setSlope(floatFeatureValues[a][9]); if(fabs(floatFeatureValues[a][10]-1.0f) < EPS) { ptrFeature->setPenUp(true); } else { ptrFeature->setPenUp(false); } outFeatureVec.push_back(LTKShapeFeaturePtr(ptrFeature)); ptrFeature = NULL; } LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Exiting " << "NPenShapeFeatureExtractor::extractFeatures()" << endl; return SUCCESS; }
/********************************************************************************** * AUTHOR : Bharath A. * DATE : 03-SEP-2007 * NAME : affineTransform * DESCRIPTION : scales the tracegroup according to the x and y scale factors. * After scaling, the "referenceCorner" of the tracegroup is translated to * (translateToX,translateToY) * ARGUMENTS : xScaleFactor - factor by which x dimension has to be scaled * yScaleFactor - factor by which y dimension has to be scaled * referenceCorner - corner to be retained after scaling and moved to (translateToX,translateToY) * RETURNS : SUCCESS on successful scale operation * NOTES : * CHANGE HISTROY * Author Date Description of change *************************************************************************************/ int LTKTraceGroup::affineTransform(float xScaleFactor,float yScaleFactor, float translateToX,float translateToY, TGCORNER referenceCorner) { LOG( LTKLogger::LTK_LOGLEVEL_DEBUG) << "Enter: LTKTraceGroup::translateTo()"<<endl; LTKTrace trace; vector<LTKTrace> scaledTracesVec; // holds the scaled traces floatVector scaledXVec; // scaled x channel values of a trace floatVector scaledYVec; // scaled y channel values of a trace float x, y; float xReference, yReference; float xMin=0.0f; float yMin=0.0f; float xMax=0.0f; float yMax=0.0f; int traceIndex, index; int errorCode; int numPoints; if(xScaleFactor <= 0) { LOG( LTKLogger::LTK_LOGLEVEL_ERR) << "Error: "<<EINVALID_X_SCALE_FACTOR <<": "<< getErrorMessage(EINVALID_X_SCALE_FACTOR) << "LTKTraceGroup::scale()"<<endl; LTKReturnError(EINVALID_X_SCALE_FACTOR); } if(yScaleFactor <= 0) { LOG( LTKLogger::LTK_LOGLEVEL_ERR) << "Error: "<<EINVALID_X_SCALE_FACTOR <<": "<< getErrorMessage(EINVALID_X_SCALE_FACTOR) << "LTKTraceGroup::scale()"<<endl; LTKReturnError(EINVALID_Y_SCALE_FACTOR); } if((errorCode = getBoundingBox(xMin,yMin,xMax,yMax))!=SUCCESS) { LOG( LTKLogger::LTK_LOGLEVEL_ERR) << "Error: LTKTraceGroup::affineTransform()"<<endl; LTKReturnError(errorCode); } switch(referenceCorner) { case XMIN_YMIN: xReference=xMin; yReference=yMin; break; case XMIN_YMAX: xReference=xMin; yReference=yMax; break; case XMAX_YMIN: xReference=xMax; yReference=yMin; break; case XMAX_YMAX: xReference=xMax; yReference=yMax; break; default: break;//define an exception } int numTraces = m_traceVector.size(); for(traceIndex=0; traceIndex < numTraces; ++traceIndex) { getTraceAt(traceIndex, trace); floatVector xVec; //no error handling required as the bounding box is found trace.getChannelValues(X_CHANNEL_NAME, xVec); floatVector yVec; trace.getChannelValues(Y_CHANNEL_NAME, yVec); numPoints = xVec.size(); for(index=0; index < numPoints; index++) { //the additive term is to translate back the scaled tracegroup //so that the corner asked for is preserved at the destination //(translateToX,translateToY) x = ( (xVec.at(index) * xScaleFactor)/m_xScaleFactor) + (translateToX - (xReference*(xScaleFactor/m_xScaleFactor)) ); scaledXVec.push_back(x); //the additive term is to translate back the scaled tracegroup //so that the corner asked for is preserved at the destination //(translateToX,translateToY) y= ( (yVec.at(index) * yScaleFactor)/m_yScaleFactor) + (translateToY - (yReference*(yScaleFactor/m_yScaleFactor))); scaledYVec.push_back(y); } trace.reassignChannelValues(X_CHANNEL_NAME,scaledXVec); trace.reassignChannelValues(Y_CHANNEL_NAME,scaledYVec); scaledXVec.clear(); scaledYVec.clear(); scaledTracesVec.push_back(trace); } m_traceVector = scaledTracesVec; m_xScaleFactor = xScaleFactor; m_yScaleFactor = yScaleFactor; LOG( LTKLogger::LTK_LOGLEVEL_DEBUG) << "Enter: LTKTraceGroup::affineTransform()"<<endl; return SUCCESS; }
/****************************************************************************** * AUTHOR : Bharath A. * DATE : 03-SEP-2007 * NAME : translateTo * DESCRIPTION : translates the tracegroup so that the "referenceCorner" is moved to (x,y) * ARGUMENTS : x: x value of point to which referenceCorner has to be moved * y: y value of point to which referenceCorner has to be moved * referenceCorner - the reference corner in the tracegroup that has to be moved to (x,y) * RETURNS : SUCCESS on successful translation operation * NOTES : * CHANGE HISTROY * Author Date Description of change *******************************************************************************/ int LTKTraceGroup::translateTo(float x,float y,TGCORNER referenceCorner) { LOG( LTKLogger::LTK_LOGLEVEL_DEBUG) << "Enter: LTKTraceGroup::translateTo()"<<endl; LTKTrace trace; vector<LTKTrace> translatedTracesVec; // holds the translated traces floatVector translatedXVec; // translated x channel values of a trace floatVector translatedYVec; // translated y channel values of a trace float xValue, yValue; float xReference, yReference; float xMin=0.0f; float yMin=0.0f; float xMax=0.0f; float yMax=0.0f; int errorCode; int traceIndex, index; int numPoints; if((errorCode = getBoundingBox(xMin,yMin,xMax,yMax))!=SUCCESS) { LOG( LTKLogger::LTK_LOGLEVEL_ERR) << "Error: LTKTraceGroup::translateTo()"<<endl; LTKReturnError(errorCode); } switch(referenceCorner) { case XMIN_YMIN: xReference=xMin; yReference=yMin; break; case XMIN_YMAX: xReference=xMin; yReference=yMax; break; case XMAX_YMIN: xReference=xMax; yReference=yMin; break; case XMAX_YMAX: xReference=xMax; yReference=yMax; break; default: break;//define an exception } int numTraces = getNumTraces(); for(traceIndex=0; traceIndex < numTraces; ++traceIndex) { getTraceAt(traceIndex, trace); floatVector xVec; //no error handling required as the bounding box is found trace.getChannelValues(X_CHANNEL_NAME, xVec); floatVector yVec; trace.getChannelValues(Y_CHANNEL_NAME, yVec); numPoints = xVec.size(); for(index=0; index < numPoints; index++) { xValue=xVec.at(index)+(x-xReference); translatedXVec.push_back(xValue); yValue=yVec.at(index)+(y-yReference); translatedYVec.push_back(yValue); } trace.reassignChannelValues(X_CHANNEL_NAME,translatedXVec); trace.reassignChannelValues(Y_CHANNEL_NAME,translatedYVec); translatedXVec.clear(); translatedYVec.clear(); translatedTracesVec.push_back(trace); } m_traceVector=translatedTracesVec; LOG( LTKLogger::LTK_LOGLEVEL_DEBUG) << "Exit: LTKTraceGroup::translateTo()"<<endl; return SUCCESS; }