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
e280ae
#ifdef _MSC_VER
Toshihiro Shimizu 890ddd
#pragma warning(disable : 4996)
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 79e39b
#include <memory></memory>
Shinya Kitaoka 79e39b
Toshihiro Shimizu 890ddd
#include <stdlib.h></stdlib.h>
Toshihiro Shimizu 890ddd
#include <stdio.h></stdio.h>
Toshihiro Shimizu 890ddd
#include <math.h></math.h>
Toshihiro Shimizu 890ddd
#include <string.h></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
Shinya Kitaoka 120a6e
CPatternPosition::~CPatternPosition() { m_pos.clear(); }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool CPatternPosition::isInSet(const int nbSet, const int *set, const int val) {
Shinya Kitaoka 120a6e
  for (int i = 0; i < nbSet; i++)
Shinya Kitaoka 120a6e
    if (set[i] == val) return true;
Shinya Kitaoka 120a6e
  return false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Campbell Barton b3bd84
static int pp_intCompare(const void *a, const void *b) {
Shinya Kitaoka 120a6e
  int *aa = (int *)a;
Shinya Kitaoka 120a6e
  int *bb = (int *)b;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (*aa < *bb) return -1;
Shinya Kitaoka 120a6e
  if (*aa > *bb) return 1;
Shinya Kitaoka 120a6e
  return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void CPatternPosition::makeRandomPositions(const int nbPat, const int nbPixel,
Shinya Kitaoka 120a6e
                                           const int lX, const int lY,
Shinya Kitaoka 120a6e
                                           const UCHAR *sel) {
Shinya Kitaoka 120a6e
  try {
Shinya Kitaoka 120a6e
    const UCHAR *pSel = sel;
Shinya Kitaoka 120a6e
    int threshold     = RAND_MAX * (double)nbPat / (double)nbPixel;
Shinya Kitaoka 120a6e
    for (int y = 0; y < lY; y++)
Shinya Kitaoka 120a6e
      for (int x = 0; x < lX; x++, pSel++)
Shinya Kitaoka 120a6e
        if (*pSel > (UCHAR)0) {
Shinya Kitaoka 120a6e
          if (rand() < threshold) {
Shinya Kitaoka 120a6e
            SPOINT xyp = {x, y};
Shinya Kitaoka 120a6e
            m_pos.push_back(xyp);
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
  } catch (exception) {
Shinya Kitaoka 120a6e
    char s[50];
Shinya Kitaoka 120a6e
    sprintf(s, "in Pattern Position Generation");
Shinya Kitaoka 120a6e
    throw SMemAllocError(s);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void CPatternPosition::getPosAroundThis(const int lX, const int lY,
Shinya Kitaoka 120a6e
                                        const UCHAR *lSel, const int xx,
Shinya Kitaoka 120a6e
                                        const int yy, int &xPos, int &yPos) {
Shinya Kitaoka 120a6e
  vector<spoint> ddc;</spoint>
Shinya Kitaoka 120a6e
  prepareCircle(ddc, 2.0);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int qx = 0, qy = 0, q = 0;
Shinya Kitaoka 120a6e
  for (vector<spoint>::iterator p = ddc.begin(); p != ddc.end(); p++) {</spoint>
Shinya Kitaoka 120a6e
    int x = xx + p->x;
Shinya Kitaoka 120a6e
    int y = yy + p->y;
Shinya Kitaoka 120a6e
    if (x >= 0 && y >= 0 && x < lX && y < lY)
Shinya Kitaoka 120a6e
      if (*(lSel + y * lX + x) > (UCHAR)0) {
Shinya Kitaoka 120a6e
        qx += x;
Shinya Kitaoka 120a6e
        qy += y;
Shinya Kitaoka 120a6e
        q++;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (q > 0) {
Shinya Kitaoka 120a6e
    double dx = (double)qx / (double)q;
Shinya Kitaoka 120a6e
    double dy = (double)qy / (double)q;
Shinya Kitaoka 120a6e
    xPos      = I_ROUND(dx);
Shinya Kitaoka 120a6e
    yPos      = I_ROUND(dy);
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    xPos = xx;
Shinya Kitaoka 120a6e
    yPos = yy;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool CPatternPosition::findEmptyPos(const int lX, const int lY,
Shinya Kitaoka 120a6e
                                    const UCHAR *lSel, int &xPos, int &yPos,
Shinya Kitaoka 120a6e
                                    SRECT &bb) {
Shinya Kitaoka 120a6e
  int y = 0;
Shinya Kitaoka 120a6e
  for (y = 0; y <= yPos; y++)
Shinya Kitaoka 120a6e
    for (int x = xPos; x <= bb.x1; x++)
Shinya Kitaoka 120a6e
      if (*(lSel + y * lX + x) == (UCHAR)1) {
Shinya Kitaoka 120a6e
        //				getPosAroundThis(lX,lY,lSel,x,y,xPos,yPos);
Shinya Kitaoka 120a6e
        xPos = x;
Shinya Kitaoka 120a6e
        yPos = y;
Shinya Kitaoka 120a6e
        return true;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (y = yPos; y <= bb.y1; y++)
Shinya Kitaoka 120a6e
    for (int x = bb.x0; x <= bb.x1; x++)
Shinya Kitaoka 120a6e
      if (*(lSel + y * lX + x) == (UCHAR)1) {
Shinya Kitaoka 120a6e
        //				getPosAroundThis(lX,lY,lSel,x,y,xPos,yPos);
Shinya Kitaoka 120a6e
        xPos = x;
Shinya Kitaoka 120a6e
        yPos = y;
Shinya Kitaoka 120a6e
        return true;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
  return false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void CPatternPosition::eraseCurrentArea(const int lX, const int lY, UCHAR *lSel,
Shinya Kitaoka 120a6e
                                        vector<spoint> &ddc, const int xx,</spoint>
Shinya Kitaoka 120a6e
                                        const int yy) {
Shinya Kitaoka 120a6e
  for (vector<spoint>::iterator pDdc = ddc.begin(); pDdc != ddc.end(); pDdc++) {</spoint>
Shinya Kitaoka 120a6e
    int x = xx + pDdc->x;
Shinya Kitaoka 120a6e
    int y = yy + pDdc->y;
Shinya Kitaoka 120a6e
    if (x >= 0 && y >= 0 && x < lX && y < lY) {
Shinya Kitaoka 120a6e
      UCHAR *pSel                      = lSel + y * lX + x;
Shinya Kitaoka 120a6e
      if (*(pSel) == (UCHAR)1) *(pSel) = (UCHAR)2;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void CPatternPosition::sel0255To01(const int lX, const int lY, UCHAR *sel,
Shinya Kitaoka 120a6e
                                   SRECT &bb) {
Shinya Kitaoka 120a6e
  UCHAR *pSel = sel;
Shinya Kitaoka 120a6e
  bb.x0       = lX;
Shinya Kitaoka 120a6e
  bb.y0       = lY;
Shinya Kitaoka 120a6e
  bb.x1       = -1;
Shinya Kitaoka 120a6e
  bb.y1       = -1;
Shinya Kitaoka 120a6e
  for (int y = 0; y < lY; y++)
Shinya Kitaoka 120a6e
    for (int x = 0; x < lX; x++, pSel++)
Shinya Kitaoka 120a6e
      if (*pSel >= (UCHAR)1) {
Shinya Kitaoka 120a6e
        *pSel = (UCHAR)1;
Shinya Kitaoka 120a6e
        bb.x0 = std::min(x, bb.x0);
Shinya Kitaoka 120a6e
        bb.x1 = std::max(x, bb.x1);
Shinya Kitaoka 120a6e
        bb.y0 = std::min(y, bb.y0);
Shinya Kitaoka 120a6e
        bb.y1 = std::max(y, bb.y1);
Shinya Kitaoka 120a6e
      }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void CPatternPosition::prepareCircle(vector<spoint> &v, const double r) {</spoint>
Shinya Kitaoka 120a6e
  try {
Shinya Kitaoka 120a6e
    double r2 = r * r;
Shinya Kitaoka 120a6e
    int rr    = (int)r + 1;
Shinya Kitaoka 120a6e
    for (int y = -rr; y <= rr; y++)
Shinya Kitaoka 120a6e
      for (int x = -rr; x <= rr; x++)
Shinya Kitaoka 120a6e
        if ((double)(x * x + y * y) <= r2) {
Shinya Kitaoka 120a6e
          SPOINT sp = {x, y};
Shinya Kitaoka 120a6e
          v.push_back(sp);
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
  } catch (exception) {
Shinya Kitaoka 120a6e
    char s[50];
Shinya Kitaoka 120a6e
    sprintf(s, "Position Generation");
Shinya Kitaoka 120a6e
    throw SMemAllocError(s);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void CPatternPosition::makeDDPositions(const int lX, const int lY, UCHAR *sel,
Shinya Kitaoka 120a6e
                                       const double minD, const double maxD) {
Shinya Kitaoka 120a6e
  const int maxNbDDC = 20;
Shinya Kitaoka 120a6e
  vector<spoint> ddc[maxNbDDC];</spoint>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Checking parameters
Shinya Kitaoka 120a6e
  if (lX <= 0 || lY <= 0 || !sel) return;
Shinya Kitaoka 120a6e
  if (minD > maxD) return;
Shinya Kitaoka 120a6e
  // Preparing circles
Shinya Kitaoka 120a6e
  int nbDDC = fabs(maxD - minD) < 0.001 ? 1 : maxNbDDC;
Shinya Kitaoka 120a6e
  try {
Shinya Kitaoka 120a6e
    if (nbDDC == 1) {
Shinya Kitaoka 120a6e
      prepareCircle(ddc[0], minD);
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      double dDist = (maxD - minD) / (double)(nbDDC - 1);
Shinya Kitaoka 120a6e
      double dist  = minD;
Shinya Kitaoka 120a6e
      for (int i = 0; i < nbDDC; i++, dist += dDist)
Shinya Kitaoka 120a6e
        prepareCircle(ddc[i], dist);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  } catch (SMemAllocError) {
Shinya Kitaoka 120a6e
    throw;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  // Preparing local selection
Shinya Kitaoka 120a6e
  std::unique_ptr<uchar[]> lSel(new UCHAR[lX * lY]);</uchar[]>
Shinya Kitaoka 120a6e
  if (!lSel) {
Shinya Kitaoka 120a6e
    char s[50];
Shinya Kitaoka 120a6e
    sprintf(s, "in Pattern Position Generation");
Shinya Kitaoka 120a6e
    throw SMemAllocError(s);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  memcpy(lSel.get(), sel, lX * lY * sizeof(UCHAR));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  SRECT bb;
Shinya Kitaoka 120a6e
  sel0255To01(lX, lY, lSel.get(), bb);
Shinya Kitaoka 120a6e
  if (bb.x0 > bb.x1 || bb.y0 > bb.y1) {
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  try {
Shinya Kitaoka 120a6e
    int x = 0, y = 0;
Shinya Kitaoka 120a6e
    while (findEmptyPos(lX, lY, lSel.get(), x, y, bb)) {
Shinya Kitaoka 120a6e
      SPOINT sp = {x, y};
Shinya Kitaoka 120a6e
      m_pos.push_back(sp);
Shinya Kitaoka 120a6e
      int iddc = nbDDC == 1 ? 0 : rand() % nbDDC;
Shinya Kitaoka 120a6e
      eraseCurrentArea(lX, lY, lSel.get(), ddc[iddc], sp.x, sp.y);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  } catch (exception) {
Shinya Kitaoka 120a6e
    char s[50];
Shinya Kitaoka 120a6e
    sprintf(s, "in Pattern Position Generation");
Shinya Kitaoka 120a6e
    throw SMemAllocError(s);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  //	memcpy(sel,lSel,lX*lY);
Toshihiro Shimizu 890ddd
}