|
|
//#include "stdafx.h"
|
|
|
#include "pch.h"
|
|
|
#include "GSurface.h"
|
|
|
//#include "BaseElements.h"
|
|
|
#include <vector>
|
|
|
#include <numeric>
|
|
|
#include <algorithm>
|
|
|
using namespace std;
|
|
|
|
|
|
GSurface::GSurface()
|
|
|
:m_u(nullptr)
|
|
|
{
|
|
|
memset(m_num, 0, sizeof(int) * 2);
|
|
|
memset(m_delt, 0, sizeof(double) * 2);
|
|
|
memset(m_P0, 0, sizeof(double) * 2);
|
|
|
memset(m_range, 0, sizeof(double) * 2);
|
|
|
}
|
|
|
|
|
|
|
|
|
GSurface::~GSurface()
|
|
|
{
|
|
|
Clear();
|
|
|
}
|
|
|
|
|
|
bool GSurface::ReadDfg(FILE* fr)
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
int numx = 0, numy= 0;
|
|
|
double xmin, ymin, dx, dy, zmin, zmax;
|
|
|
|
|
|
|
|
|
fseek(fr, 3, SEEK_CUR); fread((char *)(&numx), 4, 1, fr);
|
|
|
fseek(fr,3, SEEK_CUR); fread((char *)(&numy), 4, 1, fr);
|
|
|
fseek(fr,6, SEEK_CUR); fread((char *)(&xmin), 8, 1, fr);
|
|
|
fseek(fr,6, SEEK_CUR); fread((char *)(&ymin), 8, 1, fr);
|
|
|
fseek(fr,6, SEEK_CUR); fread((char *)(&dx), 8, 1, fr);
|
|
|
fseek(fr,6, SEEK_CUR); fread((char *)(&dy), 8, 1, fr);
|
|
|
fseek(fr,6, SEEK_CUR); fread((char *)(&zmin), 8, 1, fr);
|
|
|
fseek(fr,6, SEEK_CUR); fread((char *)(&zmax), 8, 1, fr);
|
|
|
|
|
|
char format = 8;
|
|
|
fread(&format, 1, 1, fr);
|
|
|
//fr.Read(&format, 1);
|
|
|
|
|
|
Create(numx, numy, xmin, ymin, dx, dy);
|
|
|
m_range[0] = zmin;
|
|
|
m_range[1] = zmax;
|
|
|
|
|
|
int i, nn;
|
|
|
nn = numx*numy;
|
|
|
|
|
|
|
|
|
switch (format)
|
|
|
{
|
|
|
case 2: //short
|
|
|
{
|
|
|
|
|
|
short* v = new short[numx];
|
|
|
for (int j = 0; j < numy; ++j)
|
|
|
{
|
|
|
|
|
|
fread(v, 2 * numx,1,fr);
|
|
|
for (i = 0; i < numx; ++i)
|
|
|
{
|
|
|
m_u[j*numx + i] = v[i];
|
|
|
}
|
|
|
}
|
|
|
delete v;
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
case 4: //float
|
|
|
{
|
|
|
|
|
|
float* v = new float[numx];
|
|
|
for (int j = 0; j < numy; ++j)
|
|
|
{
|
|
|
fread(v, 4 * numx, 1, fr);
|
|
|
|
|
|
for (i = 0; i < numx; ++i)
|
|
|
{
|
|
|
m_u[j*numx + i] = v[i];
|
|
|
}
|
|
|
}
|
|
|
delete v;
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
default: //double
|
|
|
fread(m_u, sizeof(double)*nn,1,fr); //2531272
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
bool GSurface::ReadDfg(const char* filename)
|
|
|
{
|
|
|
FILE* fr = fopen(filename, "rb");
|
|
|
if (nullptr == fr)
|
|
|
return false;
|
|
|
|
|
|
bool bflag = ReadDfg(fr);
|
|
|
|
|
|
fclose(fr);
|
|
|
|
|
|
return bflag;
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
bool GSurface::WriteDfg(FILE* fw)
|
|
|
{
|
|
|
|
|
|
|
|
|
double flen;
|
|
|
//unsigned long ll;
|
|
|
//unsigned short ss;
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
int numx, numy;
|
|
|
double xmin, ymin, xmax, ymax, zmin, zmax, dx, dy;
|
|
|
xmin = m_P0[0];
|
|
|
ymin = m_P0[1];
|
|
|
xmax = m_P0[0] + m_num[0] * m_delt[0];
|
|
|
ymax = m_P0[1] + m_num[1] * m_delt[1];
|
|
|
dx = m_delt[0];
|
|
|
dy = m_delt[1];
|
|
|
numx = m_num[0];
|
|
|
numy = m_num[1];
|
|
|
zmin = 1;
|
|
|
|
|
|
|
|
|
|
|
|
fwrite("m=\n", 1, 3, fw); fwrite((char *)(&numx), 4, 1, fw);
|
|
|
fwrite("n=\n", 1, 3, fw); fwrite((char *)(&numy), 4, 1, fw);
|
|
|
fwrite("xmin=\n", 1, 6, fw); fwrite((char *)(&xmin), 8, 1, fw);
|
|
|
fwrite("ymin=\n", 1, 6, fw); fwrite((char *)(&ymin), 8, 1, fw);
|
|
|
fwrite(" dx=\n", 1, 6, fw); fwrite((char *)(&dx), 8, 1, fw);
|
|
|
fwrite(" dy=\n", 1, 6, fw); fwrite((char *)(&dy), 8, 1, fw);
|
|
|
int i;
|
|
|
|
|
|
|
|
|
zmin = m_range[0];
|
|
|
zmax = m_range[1];
|
|
|
fwrite("zmin=\n", 1, 6, fw); fwrite((char *)(&zmin), 8, 1, fw);
|
|
|
fwrite("zmax=\n", 1, 6, fw); fwrite((char *)(&zmax), 8, 1, fw);
|
|
|
|
|
|
char nDataType = 8;
|
|
|
fwrite(&nDataType, 1, 1, fw);
|
|
|
|
|
|
//////////////////////////////////////////
|
|
|
flen = numx*numy;
|
|
|
switch (nDataType)
|
|
|
{
|
|
|
case 2: //short
|
|
|
{
|
|
|
short v;
|
|
|
for (int j = 0; j < numy; ++j)
|
|
|
{
|
|
|
|
|
|
for (i = 0; i < numx; ++i)
|
|
|
{
|
|
|
v = (short)m_u[j*numx + i];
|
|
|
fwrite((char *)(&v), 2, 1, fw);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
case 4: //float
|
|
|
{
|
|
|
float v;
|
|
|
for (int j = 0; j < numy; ++j)
|
|
|
{
|
|
|
|
|
|
for (i = 0; i < numx; ++i)
|
|
|
{
|
|
|
v = (float)m_u[j*numx + i];
|
|
|
fwrite((char *)(&v), 4, 1, fw);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
case 8: //double
|
|
|
default:
|
|
|
for (int j = 0; j < numy; ++j)
|
|
|
{
|
|
|
|
|
|
fwrite((char *)(m_u + j*numx), 8, numx, fw);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return 1;
|
|
|
}
|
|
|
bool GSurface::WriteDfg(const char* filename)
|
|
|
{
|
|
|
FILE* fw = fopen(filename, "wb");
|
|
|
if (nullptr == fw)
|
|
|
return false;
|
|
|
|
|
|
bool bflag = WriteDfg(fw);
|
|
|
|
|
|
fclose(fw);
|
|
|
|
|
|
return bflag;
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
int GSurface::Create(int numx, int numy, double x0, double y0, double dx, double dy)
|
|
|
{
|
|
|
Clear();
|
|
|
m_num[0] = numx;
|
|
|
m_num[1] = numy;
|
|
|
m_P0[0] = x0;
|
|
|
m_P0[1] = y0;
|
|
|
m_delt[0] = dx;
|
|
|
m_delt[1] = dy;
|
|
|
|
|
|
int N = numx*numy;
|
|
|
m_u = new double[N];
|
|
|
for (int i = 0; i < N; i++)
|
|
|
m_u[i] = 1e31;
|
|
|
|
|
|
return 1;
|
|
|
}
|
|
|
int GSurface::Create(int numx, int numy, double x0, double y0, double dx, double dy,double* values, double zMin, double zMax)
|
|
|
{
|
|
|
Clear();
|
|
|
m_num[0] = numx;
|
|
|
m_num[1] = numy;
|
|
|
m_P0[0] = x0;
|
|
|
m_P0[1] = y0;
|
|
|
m_delt[0] = dx;
|
|
|
m_delt[1] = dy;
|
|
|
|
|
|
int N = numx * numy;
|
|
|
m_u = new double[N];
|
|
|
for (int i = 0; i < N; i++)
|
|
|
m_u[i] = values[i];
|
|
|
|
|
|
this->CalcRange(zMin, zMax);
|
|
|
return 1;
|
|
|
}
|
|
|
void GSurface::Clear(void) //<2F><><EFBFBD><EFBFBD>
|
|
|
{
|
|
|
memset(m_num, 0, sizeof(int) * 2);
|
|
|
memset(m_delt, 0, sizeof(double) * 2);
|
|
|
memset(m_P0, 0, sizeof(double) * 2);
|
|
|
memset(m_range, 0, sizeof(double) * 2);
|
|
|
if (m_u)
|
|
|
{
|
|
|
delete[]m_u;
|
|
|
m_u = nullptr;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
double GSurface::X(int i)
|
|
|
{
|
|
|
return m_P0[0] + m_delt[0] * i;
|
|
|
}
|
|
|
double GSurface::Y(int j)
|
|
|
{
|
|
|
return m_P0[1] + m_delt[1] * j;
|
|
|
}
|
|
|
|
|
|
int GSurface::XNum(void)
|
|
|
{
|
|
|
return m_num[0];
|
|
|
}
|
|
|
int GSurface::YNum(void)
|
|
|
{
|
|
|
return m_num[1];
|
|
|
}
|
|
|
|
|
|
double GSurface::Z(int i, int j)
|
|
|
{
|
|
|
return m_u[j*XNum() + i];
|
|
|
}
|
|
|
|
|
|
double GSurface::DeltX()
|
|
|
{
|
|
|
return m_delt[0];
|
|
|
}
|
|
|
double GSurface::DeltY()
|
|
|
{
|
|
|
return m_delt[1];
|
|
|
}
|
|
|
|
|
|
double *GSurface::GetRange()
|
|
|
{
|
|
|
return m_range;
|
|
|
}
|
|
|
|
|
|
void GSurface::CalcRange(double rangeMin, double rangeMax)
|
|
|
{
|
|
|
double dRangeMin = max(rangeMin, -1e20);
|
|
|
double dRangeMax = min(rangeMax, 1e20);
|
|
|
|
|
|
int N = XNum()*YNum();
|
|
|
double zmin, zmax;
|
|
|
zmin = 1E300; zmax = -1E300;;
|
|
|
if (rangeMin > -1E300) {
|
|
|
|
|
|
}
|
|
|
double u = 0;
|
|
|
for (int i = 1; i < N; i++)
|
|
|
{
|
|
|
u = m_u[i];
|
|
|
if (u > dRangeMax)
|
|
|
continue;
|
|
|
if (u < dRangeMin)
|
|
|
{
|
|
|
continue;
|
|
|
}
|
|
|
zmin = min(zmin, u);
|
|
|
zmax = max(zmax, u);
|
|
|
}
|
|
|
|
|
|
m_range[0] = zmin;
|
|
|
m_range[1] = zmax;
|
|
|
}
|
|
|
|
|
|
|
|
|
bool GSurface::IsInRange(double z0)
|
|
|
{
|
|
|
if (z0 > m_range[1] + 1e-6)
|
|
|
return false;
|
|
|
if (z0 < m_range[0] - 1e-6)
|
|
|
return false;
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
////ֻȡ<D6BB>ϲ<EFBFBD><CFB2>ⲿ<EFBFBD>Ľ<EFBFBD><C4BD><EFBFBD><EFBFBD><EFBFBD>ֵ
|
|
|
//double GSurface::Value(double x0, double y0, GPline* png)
|
|
|
//{
|
|
|
|
|
|
// int i, j, k;
|
|
|
// i = (int)((x0 - m_P0[0]) / m_delt[0]);
|
|
|
// if (i<0 || i>m_num[0] - 1)
|
|
|
// return 1e31;
|
|
|
|
|
|
// j = (int)((y0 - m_P0[1]) / m_delt[1]);
|
|
|
// if (j<0 || j>m_num[1] - 1)
|
|
|
// return 1e31;
|
|
|
|
|
|
// if (i == XNum() - 1 || j == YNum() - 1)
|
|
|
// return 1e31;
|
|
|
|
|
|
|
|
|
// k = i + j*m_num[0];
|
|
|
|
|
|
// //ѡ<><D1A1><EFBFBD>ϲ<EFBFBD><CFB2>ⲿ<EFBFBD>Ľ<EFBFBD><C4BD><EFBFBD>
|
|
|
// GPoint3D pt;
|
|
|
// vector<GPoint3D> dstpts;
|
|
|
|
|
|
// const int NX[4] = { i,i+1,i+1,i };
|
|
|
// const int NY[4] = {j,j,j+1,j+1};
|
|
|
// for (int kk = 0; kk < 4; kk++)
|
|
|
// {
|
|
|
// pt.x0 = this->X(NX[kk]);
|
|
|
// pt.y0 = this->Y(NY[kk]);
|
|
|
// if (0 != png->IsInside(pt.x0, pt.y0))
|
|
|
// continue;
|
|
|
// pt.z0 = this->Z(NX[kk], NY[kk]);
|
|
|
// dstpts.push_back(pt);
|
|
|
// }
|
|
|
|
|
|
|
|
|
// if (dstpts.empty() )
|
|
|
// return 1e31;
|
|
|
|
|
|
// if (dstpts.size() < 4)
|
|
|
// {
|
|
|
// vector<double> dists;
|
|
|
// double d;
|
|
|
// pt = GPoint3D(x0, y0, 0);
|
|
|
// for (int kk = 0; kk < dstpts.size(); kk++)
|
|
|
// {
|
|
|
// d = dstpts[kk].Distance2D(pt);
|
|
|
// if (d < 1e-6)
|
|
|
// return dstpts[kk].z0;
|
|
|
// dists.push_back(1.0/d);
|
|
|
// }
|
|
|
// double vv = 0.0;
|
|
|
// for (int kk = 0; kk < dstpts.size(); kk++)
|
|
|
// vv += dists[kk] * dstpts[kk].z0;
|
|
|
|
|
|
|
|
|
// vv /= double(std::accumulate(dists.begin(), dists.end(), 0.0));
|
|
|
|
|
|
// return vv;
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
// if (m_num[1] - 1 == j)
|
|
|
// {
|
|
|
// if (!IsInRange(m_u[k]) || !IsInRange(m_u[k + 1]))
|
|
|
// return 1e101;
|
|
|
// }
|
|
|
// else if (
|
|
|
// !IsInRange(m_u[k]) ||
|
|
|
// !IsInRange(m_u[k + 1]) ||
|
|
|
// !IsInRange(m_u[k + m_num[0]]) ||
|
|
|
// !IsInRange(m_u[k + m_num[0] + 1]))
|
|
|
// return 1e31;
|
|
|
|
|
|
// double kx = (x0 - X(i)) / m_delt[0];
|
|
|
// double ky = (y0 - Y(j)) / m_delt[1];
|
|
|
|
|
|
// if (fabs(kx) < 1e-6 && fabs(ky) < 1e-6)
|
|
|
// return Z(i, j);
|
|
|
|
|
|
// double z1 = Z(i, j) + kx*(Z(i + 1, j) - Z(i, j));
|
|
|
// double z2 = Z(i, j + 1) + kx*(Z(i + 1, j + 1) - Z(i, j + 1));
|
|
|
|
|
|
// double z0 = z1 + ky*(z2 - z1);
|
|
|
|
|
|
// return z0;
|
|
|
|
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
|
|
double GSurface::Z(double x0, double y0)
|
|
|
{
|
|
|
int i, j, k;
|
|
|
i = (int)((x0 - m_P0[0]) / m_delt[0]);
|
|
|
if (i<0 || i>m_num[0] - 1)
|
|
|
return 1e31;
|
|
|
|
|
|
j = (int)((y0 - m_P0[1]) / m_delt[1]);
|
|
|
if (j<0 || j>m_num[1] - 1)
|
|
|
return 1e31;
|
|
|
|
|
|
if (i == XNum() - 1 || j == YNum() - 1)
|
|
|
return 1e31;
|
|
|
|
|
|
|
|
|
k = i + j*m_num[0];
|
|
|
|
|
|
|
|
|
if (m_num[1] - 1 == j)
|
|
|
{
|
|
|
if (!IsInRange(m_u[k]) || !IsInRange(m_u[k + 1]))
|
|
|
return 1e101;
|
|
|
}
|
|
|
else if (
|
|
|
!IsInRange(m_u[k]) ||
|
|
|
!IsInRange(m_u[k + 1]) ||
|
|
|
!IsInRange(m_u[k + m_num[0]]) ||
|
|
|
!IsInRange(m_u[k + m_num[0] + 1]))
|
|
|
return 1e31;
|
|
|
|
|
|
double kx = (x0 - X(i)) / m_delt[0];
|
|
|
double ky = (y0 - Y(j)) / m_delt[1];
|
|
|
|
|
|
if (fabs(kx) < 1e-6 && fabs(ky) < 1e-6)
|
|
|
return Z(i, j);
|
|
|
|
|
|
double z1 = Z(i, j) + kx*(Z(i + 1, j) - Z(i, j));
|
|
|
double z2 = Z(i, j + 1) + kx*(Z(i + 1, j + 1) - Z(i, j + 1));
|
|
|
|
|
|
double z0 = z1 + ky*(z2 - z1);
|
|
|
|
|
|
return z0;
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
void GSurface::setZ(int i, int j, double z)
|
|
|
{
|
|
|
|
|
|
m_u[j*XNum() + i] = z;
|
|
|
|
|
|
}
|