Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// PatternPosition.cpp: implementation of the CPatternPosition class.
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//////////////////////////////////////////////////////////////////////
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef WIN32
Toshihiro Shimizu 890ddd
#pragma warning(disable : 4996)
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include <stdlib.h>
Toshihiro Shimizu 890ddd
#include <stdio.h>
Toshihiro Shimizu 890ddd
#include <math.h>
Toshihiro Shimizu 890ddd
#include <string.h>
Toshihiro Shimizu 890ddd
#include "PatternPosition.h"
Toshihiro Shimizu 890ddd
#include "SError.h"
Toshihiro Shimizu 890ddd
#include "SDef.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//////////////////////////////////////////////////////////////////////
Toshihiro Shimizu 890ddd
// Construction/Destruction
Toshihiro Shimizu 890ddd
//////////////////////////////////////////////////////////////////////
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
using namespace std;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
CPatternPosition::~CPatternPosition()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_pos.clear();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool CPatternPosition::isInSet(const int nbSet, const int *set, const int val)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	for (int i = 0; i < nbSet; i++)
Toshihiro Shimizu 890ddd
		if (set[i] == val)
Toshihiro Shimizu 890ddd
			return true;
Toshihiro Shimizu 890ddd
	return false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int pp_intCompare(const void *a, const void *b)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int *aa = (int *)a;
Toshihiro Shimizu 890ddd
	int *bb = (int *)b;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (*aa < *bb)
Toshihiro Shimizu 890ddd
		return -1;
Toshihiro Shimizu 890ddd
	if (*aa > *bb)
Toshihiro Shimizu 890ddd
		return 1;
Toshihiro Shimizu 890ddd
	return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void CPatternPosition::makeRandomPositions(const int nbPat, const int nbPixel,
Toshihiro Shimizu 890ddd
										   const int lX, const int lY, const UCHAR *sel)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	try {
Toshihiro Shimizu 890ddd
		const UCHAR *pSel = sel;
Toshihiro Shimizu 890ddd
		int threshold = RAND_MAX * (double)nbPat / (double)nbPixel;
Toshihiro Shimizu 890ddd
		for (int y = 0; y < lY; y++)
Toshihiro Shimizu 890ddd
			for (int x = 0; x < lX; x++, pSel++)
Toshihiro Shimizu 890ddd
				if (*pSel > (UCHAR)0) {
Toshihiro Shimizu 890ddd
					if (rand() < threshold) {
Toshihiro Shimizu 890ddd
						SPOINT xyp = {x, y};
Toshihiro Shimizu 890ddd
						m_pos.push_back(xyp);
Toshihiro Shimizu 890ddd
					}
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
	} catch (exception) {
Toshihiro Shimizu 890ddd
		char s[50];
Toshihiro Shimizu 890ddd
		sprintf(s, "in Pattern Position Generation");
Toshihiro Shimizu 890ddd
		throw SMemAllocError(s);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void CPatternPosition::getPosAroundThis(const int lX, const int lY, const UCHAR *lSel,
Toshihiro Shimizu 890ddd
										const int xx, const int yy,
Toshihiro Shimizu 890ddd
										int &xPos, int &yPos)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	vector<SPOINT> ddc;
Toshihiro Shimizu 890ddd
	prepareCircle(ddc, 2.0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int qx = 0, qy = 0, q = 0;
Toshihiro Shimizu 890ddd
	for (vector<SPOINT>::iterator p = ddc.begin();
Toshihiro Shimizu 890ddd
		 p != ddc.end();
Toshihiro Shimizu 890ddd
		 p++) {
Toshihiro Shimizu 890ddd
		int x = xx + p->x;
Toshihiro Shimizu 890ddd
		int y = yy + p->y;
Toshihiro Shimizu 890ddd
		if (x >= 0 && y >= 0 && x < lX && y < lY)
Toshihiro Shimizu 890ddd
			if (*(lSel + y * lX + x) > (UCHAR)0) {
Toshihiro Shimizu 890ddd
				qx += x;
Toshihiro Shimizu 890ddd
				qy += y;
Toshihiro Shimizu 890ddd
				q++;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (q > 0) {
Toshihiro Shimizu 890ddd
		double dx = (double)qx / (double)q;
Toshihiro Shimizu 890ddd
		double dy = (double)qy / (double)q;
Toshihiro Shimizu 890ddd
		xPos = I_ROUND(dx);
Toshihiro Shimizu 890ddd
		yPos = I_ROUND(dy);
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		xPos = xx;
Toshihiro Shimizu 890ddd
		yPos = yy;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool CPatternPosition::findEmptyPos(const int lX, const int lY, const UCHAR *lSel,
Toshihiro Shimizu 890ddd
									int &xPos, int &yPos, SRECT &bb)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int y = 0;
Toshihiro Shimizu 890ddd
	for (y = 0; y <= yPos; y++)
Toshihiro Shimizu 890ddd
		for (int x = xPos; x <= bb.x1; x++)
Toshihiro Shimizu 890ddd
			if (*(lSel + y * lX + x) == (UCHAR)1) {
Toshihiro Shimizu 890ddd
				//				getPosAroundThis(lX,lY,lSel,x,y,xPos,yPos);
Toshihiro Shimizu 890ddd
				xPos = x;
Toshihiro Shimizu 890ddd
				yPos = y;
Toshihiro Shimizu 890ddd
				return true;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (y = yPos; y <= bb.y1; y++)
Toshihiro Shimizu 890ddd
		for (int x = bb.x0; x <= bb.x1; x++)
Toshihiro Shimizu 890ddd
			if (*(lSel + y * lX + x) == (UCHAR)1) {
Toshihiro Shimizu 890ddd
				//				getPosAroundThis(lX,lY,lSel,x,y,xPos,yPos);
Toshihiro Shimizu 890ddd
				xPos = x;
Toshihiro Shimizu 890ddd
				yPos = y;
Toshihiro Shimizu 890ddd
				return true;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
	return false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void CPatternPosition::eraseCurrentArea(const int lX, const int lY, UCHAR *lSel,
Toshihiro Shimizu 890ddd
										vector<SPOINT> &ddc, const int xx, const int yy)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	for (vector<SPOINT>::iterator pDdc = ddc.begin();
Toshihiro Shimizu 890ddd
		 pDdc != ddc.end();
Toshihiro Shimizu 890ddd
		 pDdc++) {
Toshihiro Shimizu 890ddd
		int x = xx + pDdc->x;
Toshihiro Shimizu 890ddd
		int y = yy + pDdc->y;
Toshihiro Shimizu 890ddd
		if (x >= 0 && y >= 0 && x < lX && y < lY) {
Toshihiro Shimizu 890ddd
			UCHAR *pSel = lSel + y * lX + x;
Toshihiro Shimizu 890ddd
			if (*(pSel) == (UCHAR)1)
Toshihiro Shimizu 890ddd
				*(pSel) = (UCHAR)2;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void CPatternPosition::sel0255To01(const int lX, const int lY, UCHAR *sel, SRECT &bb)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	UCHAR *pSel = sel;
Toshihiro Shimizu 890ddd
	bb.x0 = lX;
Toshihiro Shimizu 890ddd
	bb.y0 = lY;
Toshihiro Shimizu 890ddd
	bb.x1 = -1;
Toshihiro Shimizu 890ddd
	bb.y1 = -1;
Toshihiro Shimizu 890ddd
	for (int y = 0; y < lY; y++)
Toshihiro Shimizu 890ddd
		for (int x = 0; x < lX; x++, pSel++)
Toshihiro Shimizu 890ddd
			if (*pSel >= (UCHAR)1) {
Toshihiro Shimizu 890ddd
				*pSel = (UCHAR)1;
Toshihiro Shimizu 890ddd
				bb.x0 = MIN(x, bb.x0);
Toshihiro Shimizu 890ddd
				bb.x1 = MAX(x, bb.x1);
Toshihiro Shimizu 890ddd
				bb.y0 = MIN(y, bb.y0);
Toshihiro Shimizu 890ddd
				bb.y1 = MAX(y, bb.y1);
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void CPatternPosition::prepareCircle(vector<SPOINT> &v, const double r)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	try {
Toshihiro Shimizu 890ddd
		double r2 = r * r;
Toshihiro Shimizu 890ddd
		int rr = (int)r + 1;
Toshihiro Shimizu 890ddd
		for (int y = -rr; y <= rr; y++)
Toshihiro Shimizu 890ddd
			for (int x = -rr; x <= rr; x++)
Toshihiro Shimizu 890ddd
				if ((double)(x * x + y * y) <= r2) {
Toshihiro Shimizu 890ddd
					SPOINT sp = {x, y};
Toshihiro Shimizu 890ddd
					v.push_back(sp);
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
	} catch (exception) {
Toshihiro Shimizu 890ddd
		char s[50];
Toshihiro Shimizu 890ddd
		sprintf(s, "Position Generation");
Toshihiro Shimizu 890ddd
		throw SMemAllocError(s);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void CPatternPosition::makeDDPositions(const int lX, const int lY, UCHAR *sel,
Toshihiro Shimizu 890ddd
									   const double minD, const double maxD)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	const int maxNbDDC = 20;
Toshihiro Shimizu 890ddd
	vector<SPOINT> ddc[maxNbDDC];
Toshihiro Shimizu 890ddd
	UCHAR *lSel = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// Checking parameters
Toshihiro Shimizu 890ddd
	if (lX <= 0 || lY <= 0 || !sel)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	if (minD > maxD)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	// Preparing circles
Toshihiro Shimizu 890ddd
	int nbDDC = fabs(maxD - minD) < 0.001 ? 1 : maxNbDDC;
Toshihiro Shimizu 890ddd
	try {
Toshihiro Shimizu 890ddd
		if (nbDDC == 1) {
Toshihiro Shimizu 890ddd
			prepareCircle(ddc[0], minD);
Toshihiro Shimizu 890ddd
		} else {
Toshihiro Shimizu 890ddd
			double dDist = (maxD - minD) / (double)(nbDDC - 1);
Toshihiro Shimizu 890ddd
			double dist = minD;
Toshihiro Shimizu 890ddd
			for (int i = 0; i < nbDDC; i++, dist += dDist)
Toshihiro Shimizu 890ddd
				prepareCircle(ddc[i], dist);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	} catch (SMemAllocError) {
Toshihiro Shimizu 890ddd
		throw;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	// Preparing local selection
Toshihiro Shimizu 890ddd
	lSel = new UCHAR[lX * lY];
Toshihiro Shimizu 890ddd
	if (!lSel) {
Toshihiro Shimizu 890ddd
		char s[50];
Toshihiro Shimizu 890ddd
		sprintf(s, "in Pattern Position Generation");
Toshihiro Shimizu 890ddd
		throw SMemAllocError(s);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	memcpy(lSel, sel, lX * lY * sizeof(UCHAR));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	SRECT bb;
Toshihiro Shimizu 890ddd
	sel0255To01(lX, lY, lSel, bb);
Toshihiro Shimizu 890ddd
	if (bb.x0 > bb.x1 || bb.y0 > bb.y1) {
Toshihiro Shimizu 890ddd
		delete[] lSel;
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	try {
Toshihiro Shimizu 890ddd
		int x = 0, y = 0;
Toshihiro Shimizu 890ddd
		while (findEmptyPos(lX, lY, lSel, x, y, bb)) {
Toshihiro Shimizu 890ddd
			SPOINT sp = {x, y};
Toshihiro Shimizu 890ddd
			m_pos.push_back(sp);
Toshihiro Shimizu 890ddd
			int iddc = nbDDC == 1 ? 0 : rand() % nbDDC;
Toshihiro Shimizu 890ddd
			eraseCurrentArea(lX, lY, lSel, ddc[iddc], sp.x, sp.y);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		delete[] lSel;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	} catch (exception) {
Toshihiro Shimizu 890ddd
		delete[] lSel;
Toshihiro Shimizu 890ddd
		char s[50];
Toshihiro Shimizu 890ddd
		sprintf(s, "in Pattern Position Generation");
Toshihiro Shimizu 890ddd
		throw SMemAllocError(s);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	//	memcpy(sel,lSel,lX*lY);
Toshihiro Shimizu 890ddd
}