我遇到了这段代码,但不知道如何用C#编写它:
bool getBestFitPlane(unsigned int vcount,
const float *points,
unsigned int vstride,
const float *weights,
unsigned int wstride,
float *plane)
{
bool ret = false;
SinglePrecision::Vec3 kOrigin(0,0,0);
float wtotal = 0;
if ( 1 )
{
const char *source = (const char *) points;
const char *wsource = (const char *) weights;
for (unsigned int i=0; i<vcount; i++)
{
const float *p = (const float *) source;
float w = 1;
if ( wsource )
{
const float *ws = (const float *) wsource;
w = *ws; //
wsource+=wstride;
}
kOrigin.x+=p[0]*w;
kOrigin.y+=p[1]*w;
kOrigin.z+=p[2]*w;
wtotal+=w;
source+=vstride;
}
}
float recip = 1.0f / wtotal; // reciprocol of total weighting
kOrigin.x*=recip;
kOrigin.y*=recip;
kOrigin.z*=recip;
float fSumXX=0;
float fSumXY=0;
float fSumXZ=0;
float fSumYY=0;
float fSumYZ=0;
float fSumZZ=0;
if ( 1 )
{
const char *source = (const char *) points;
const char *wsource = (const char *) weights;
for (unsigned int i=0; i<vcount; i++)
{
const float *p = (const float *) source;
float w = 1;
if ( wsource )
{
const float *ws = (const float *) wsource;
w = *ws; //
wsource+=wstride;
}
SinglePrecision::Vec3 kDiff;
kDiff.x = w*(p[0] - kOrigin.x); // apply vertex weighting!
kDiff.y = w*(p[1] - kOrigin.y);
kDiff.z = w*(p[2] - kOrigin.z);
fSumXX+= kDiff.x * kDiff.x; // sume of the squares of the differences.
fSumXY+= kDiff.x * kDiff.y; // sume of the squares of the differences.
fSumXZ+= kDiff.x * kDiff.z; // sume of the squares of the differences.
fSumYY+= kDiff.y * kDiff.y;
fSumYZ+= kDiff.y * kDiff.z;
fSumZZ+= kDiff.z * kDiff.z;
source+=vstride;
}
}
fSumXX *= recip;
fSumXY *= recip;
fSumXZ *= recip;
fSumYY *= recip;
fSumYZ *= recip;
fSumZZ *= recip;
// setup the eigensolver
SinglePrecision::Eigen kES;
kES.mElement[0][0] = fSumXX;
kES.mElement[0][1] = fSumXY;
kES.mElement[0][2] = fSumXZ;
kES.mElement[1][0] = fSumXY;
kES.mElement[1][1] = fSumYY;
kES.mElement[1][2] = fSumYZ;
kES.mElement[2][0] = fSumXZ;
kES.mElement[2][1] = fSumYZ;
kES.mElement[2][2] = fSumZZ;
// compute eigenstuff, smallest eigenvalue is in last position
kES.DecrSortEigenStuff();
SinglePrecision::Vec3 kNormal;
kNormal.x = kES.mElement[0][2];
kNormal.y = kES.mElement[1][2];
kNormal.z = kES.mElement[2][2];
// the minimum energy
plane[0] = kNormal.x;
plane[1] = kNormal.y;
plane[2] = kNormal.z;
plane[3] = 0 - kNormal.dot(kOrigin);
return ret;
}
我主要不了解const char行。它是否试图获取值数组的第一项?
答案 0 :(得分:3)
基本上,是的 - 虽然这里有一些奇怪的类型转换似乎是不必要的,至少考虑到你发布的代码片段。
该行声明一个常量(即不可更改)指针(*)指向名为'source'的char(有符号字节),并为其指定'values'开头的地址。这很奇怪,因为从参数列表中可以看出,值是一个const float *类型。
指针类型通常用于处理旧C / C ++程序中的数组,因为它们在某种程度上是可以互换的。
对于C#,您将使用内置数组类型。
[编辑]现在您已经发布了更多源代码,很明显这样做是为了让他们可以使用'source'变量指向一个浮点数块,并将它增加一个'stride'字节数(chars)必要时移动到浮子进行处理。如果需要,您当然可以设计C#代码来处理此内存布局(System.IntPtr可能对您有所帮助。)
答案 1 :(得分:2)
我主要不了解const char行。它是否试图获取值数组的第一项?
将points
强制转换为source
的目的是获取float
数组的常量字节数组(有效)版本
// use points as a byte array
const char *source = (const char *) points;
for (unsigned int i=0; i<vcount; i++)
{
// get a reference to the current position in the source array
const float *p = (const float *) source;
...
// iterate to the next series of points
source+=vstride;
}
我认为vstride
的值是12或更大。 vstride
用于跳过当前点的任意数量的字节,以便计算加权值。由于每个位置至少有3个float
点,这就是我提出至少12(3乘4)的方法。如果数组中的其他数据连同点,在z坐标和下一个点的开始之间可能会更多。
需要使用source
指针的原因是因为指针算法基于指向数据的sizeof
工作。因此(points + 12)
与(source + 12)
不同,显然vstride
与要跳过的字节数相关联(暗示points
引用可能实际上是{{1因为方便而被用作struct
数组,这在C / C ++中并不少见。)
在C#中,你不会写这样的东西。您将传入一个数组/点集合,这将是一个具有X,Y和Z float
点坐标的对象。类似地,将有一个可选的(可以float
,如null
所示)数组/权重集合,其中包含一个if (wsource)
值,表示当前坐标的权重。将它们组合在一起可能是有意义的。如果定义了float
,则点和权重具有相同数量的元素。
您不需要C#中的weights
,vcount
或vstride
变量。您可以循环遍历wstride
数组/集合,并在提供任何权重时应用权重。
Points