gpt4 book ai didi

c++ - 3D 重心点交点

转载 作者:太空宇宙 更新时间:2023-11-04 11:38:34 26 4
gpt4 key购买 nike

我首先要说的是,是的,我花了数天或数小时,但确实花了几个月的时间来解决这个问题。我喜欢直面问题,但今天我完全被困住了。

我试图确定一个点是否在 3D 空间中的三角形内,并且我有以下代码来尝试检测它。

测试:

bool D3DHandler::IsCollidingWithTerrain(D3DXVECTOR3 pos){
for (unsigned int i = 1; i < chunk.at(0).GetWidth()-1; i++){
for (unsigned int ii = 1; ii < chunk.at(0).GetWidth()-1; ii++){
if (Physics::PolyPointCollision(
NORMALVERTEX{ chunk.at(0).GetVertex(i, ii).X, chunk.at(0).GetVertex(i, ii).Y, chunk.at(0).GetVertex(i, ii).Z, { 0, 0, 0 } },
NORMALVERTEX{ chunk.at(0).GetVertex(i + 1, ii).X, chunk.at(0).GetVertex(i + 1, ii).Y, chunk.at(0).GetVertex(i + 1, ii).Z, { 0, 0, 0 } },
NORMALVERTEX{ chunk.at(0).GetVertex(i, ii + 1).X, chunk.at(0).GetVertex(i, ii + 1).Y, chunk.at(0).GetVertex(i, ii + 1).Z, { 0, 0, 0 } },
NORMALVERTEX{ pos.x, pos.y, pos.z, { 0, 0, 0 } })
||
Physics::PolyPointCollision(
NORMALVERTEX{ chunk.at(0).GetVertex(i, ii).X, chunk.at(0).GetVertex(i, ii).Y, chunk.at(0).GetVertex(i, ii).Z, { 0, 0, 0 } },
NORMALVERTEX{ chunk.at(0).GetVertex(i - 1, ii).X, chunk.at(0).GetVertex(i - 1, ii).Y, chunk.at(0).GetVertex(i - 1, ii).Z, { 0, 0, 0 } },
NORMALVERTEX{ chunk.at(0).GetVertex(i, ii - 1).X, chunk.at(0).GetVertex(i, ii - 1).Y, chunk.at(0).GetVertex(i, ii - 1).Z, { 0, 0, 0 } },
NORMALVERTEX{ pos.x, pos.y, pos.z, { 0, 0, 0 } })){
return true;
}
}
}
return false;
}

有问题的功能:

bool Physics::PolyPointCollision(NORMALVERTEX a, NORMALVERTEX b, NORMALVERTEX c, NORMALVERTEX p){
NORMALVERTEX v0 = { c.X - a.X, c.Y - a.Y, c.Z - a.Z, { 0, 0, 0 } };
NORMALVERTEX v1 = { b.X - a.X, b.Y - a.Y, b.Z - a.Z, { 0, 0, 0 } };
NORMALVERTEX v2 = { p.X - a.X, p.Y - a.Y, p.Z - a.Z, { 0, 0, 0 } };
float dot00 = (v0.X*v0.X) + (v0.Y*v0.Y) + (v0.Z * v0.Z);
float dot01 = (v0.X*v1.X) + (v0.Y*v1.Y) + (v0.Z * v1.Z);
float dot02 = (v0.X*v2.X) + (v0.Y*v2.Y) + (v0.Z * v2.Z);
float dot11 = (v1.X*v1.X) + (v1.Y*v1.Y) + (v1.Z * v1.Z);
float dot12 = (v1.X*v2.X) + (v1.Y*v2.Y) + (v1.Z * v2.Z);
float invDenom = 1 / ((dot00*dot11) - (dot01*dot01));
float u = ((dot11*dot02) - (dot01*dot12))*invDenom;
float v = ((dot00*dot12) - (dot01*dot02))*invDenom;
if (u >= 0 && v >= 0 && (v + u)<1){
return true;
}
return false;
}

我在这里做的是将网格中的 3 个点转换为要转换为三角形的地形,然后将其发送到一个函数以将其转换为测试以确定一个点是否在使用重心的三角形内坐标。然而,它在一定程度上起作用,就像我进入三角形的 X-Z 平面一样,测试将返回 true,但是它没有检测到沿 Y 轴的任何东西。我的问题是如何获得检测 Z 轴的函数,以便我确定该点在所有轴的三角形边界内。

这是我正在制作的引擎的屏幕截图,其中包含我正在尝试解释的确切情况。

http://i.stack.imgur.com/kfqnL.png

编辑:

D3DHandler.h类:

class D3DHandler{
public:
D3DHandler(HWND hWnd,int WINX,int WINY,HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow);
~D3DHandler();
bool IsCollidingWithTerrain(D3DXVECTOR3 pos);
bool DeviceCheck();
void UnlockBuffer();
void LockBuffer();
void print2DPixel(int x,int y,int r,int g,int b);
void print2DPixel(int x,int y,D3DCOLOR c);
void printVertexArray(NORMALVERTEX *vertex,int length);
void printIndexArray(NORMALVERTEX *vertex,short *indicies,int vLength,int iLength);
void printVertexArrayWireframe(NORMALVERTEX *vertex,int length);
void printIndexArrayWireframe(NORMALVERTEX *vertex,short *indicies,int vLength,int iLength);
void PrepareFrame(Player p);
void SetupLight();
void AddObjectToRoom(NORMALVERTEX* model,int mLength,short *modelIndices,int iLength,D3DXCOLOR dCol,D3DXCOLOR aCol);
void AddObjectToRoom(TEXVERTEX* model,int mLength,short *modelIndices,int iLength,D3DXCOLOR dCol,D3DXCOLOR aCol,int texId);
void AddObjectToRoom(float xPos,float yPos,float zPos,wchar_t meshName);
boolean CheckRoom();
void RenderRoom();
void RenderTerrain();
void ClearBuffer();
void SetRenders();
void LoadRoom();
void PresentParams();
void NewFont(LPCTSTR faceName,int size,int thickness, bool italic);
IDirect3DDevice9* GetDevice();
LPDIRECT3DTEXTURE9 grabTexture(int index);
void PresentFrame();
D3DMesh* GrabMesh(wchar_t meshName);
void RenderFont(int fontId,char* text,int x,int y,D3DCOLOR colour,LPD3DXSPRITE sprite,DWORD alignment);
void ResetDevice(HWND hWnd);
void RebootDevice(HWND hWnd);
bool isActive;
private:
D3DVIEWPORT9 viewPort;
D3DPRESENT_PARAMETERS d3dpp;
D3DRoom *room;
D3DXMATRIX matRotateX,matRotateY,matRotateZ,matTranslate,matScale,matView,matProjection;
D3DLIGHT9 light;
D3DMATERIAL9 material;
IDirect3D9* pDirect3D;
IDirect3DDevice9* pDevice;
IDirect3DSurface9* pBackBuffer;
D3DLOCKED_RECT backRect;
LPDIRECT3DVERTEXBUFFER9 vBuffer;
LPDIRECT3DINDEXBUFFER9 iBuffer;
HWND hWind;
std::vector<D3DTerrain> chunk;
std::vector<D3DFont> font;
std::vector<LPDIRECT3DTEXTURE9> texture;
std::vector<D3DMesh> mesh;
int WINX,WINY;

HINSTANCE hInst;
HINSTANCE hPrev;
LPSTR lpCmdLne;
int nCmdShw;
};

D3DTerrain 类(这就是“ block ”):

class D3DTerrain{
public:
D3DTerrain(float xPos,float yPos,float zPos);
~D3DTerrain();
void Render(LPDIRECT3DDEVICE9 pDevice);
void Load(LPDIRECT3DDEVICE9 pDevice);
void Load(LPDIRECT3DDEVICE9 PDevice,char* fName,wchar_t* tName);
void Release(){vBuffer->Release();iBuffer->Release();m_texture->Release();m_textureDetail->Release();m_vertecies=NULL;m_indices=NULL;m_height=NULL;}
TEX2VERTEX GetVertex(unsigned int x,unsigned int y){return m_vertex[x*(int)m_width+y];}
UINT GetWidth(){return m_width;}
private:
IDirect3DVertexBuffer9 *vBuffer;
IDirect3DIndexBuffer9 *iBuffer;
TEX2VERTEX *m_vertex;
UCHAR* m_height;
UINT m_vertecies;
UINT m_indices;
UINT m_width;
char m_fileLoc[128];
wchar_t m_textureName[128];
LPDIRECT3DTEXTURE9 m_texture,m_textureDetail;
D3DXMATRIX m_rotX,m_rotY,m_rotZ,m_translate,m_scale,m_textureCords;
};

顶点类型:

struct NORMALVERTEX{
FLOAT X, Y, Z;
D3DVECTOR NORMAL;
};
struct T_NORMALVERTEX{
FLOAT X, Y, Z;
D3DVECTOR NORMAL;
FLOAT U, V;
};
struct TEXVERTEX{
FLOAT X, Y, Z;
FLOAT U, V;
};
struct TEX2VERTEX{
FLOAT X, Y, Z;
FLOAT U1, U2, V1, V2;
};

我不是来这里批评我的编程的,它很乱,因为我只是想让一个主要功能正常工作,然后我会优化和重组我的代码,这是一个个人项目,我知道它很粗糙.

最佳答案

好吧,不管我以前的方法是什么原因是不正确的,所以我寻找了如何找到重心坐标的数学定义,其中涉及 vector 长度和叉积。虽然平方根很慢,但它有效,我将在未来调整此功能的工作方式,并尝试清理和优化它以达到我的最佳能力,但这就是我解决此问题的方式。

UtilityFunctions.h

#include "DataTypes.h"
namespace Util{
float map(float in, float minA, float maxA, float minB, float maxB);
float dot(float ax, float ay, float az, float bx, float by, float bz);
float dot(Point3D a, Point3D b);
float length(Point3D p);
Point3D sub(Point3D a, Point3D b);
Point3D toBarycentric(Point3D a, Point3D b, Point3D c, Point3D p);
Point3D cross(Point3D a, Point3D b);
};

UtilityFunctions.cpp

#include <vector>
#include <stdio.h>
#include <math.h>
#include "UtilityFunctions.h"

float Util::map(float in, float minA, float maxA, float minB, float maxB){
float ratio = 0.0f;
if (abs(maxA - minA)>0){
ratio = (maxB - minB) / (maxA - minA);
}
return (in - minA)*ratio + minB;
}

float Util::dot(float ax, float ay, float az, float bx, float by, float bz){ return (ax*bx) + (ay*by) + (az*bz); }
float Util::dot(Point3D a, Point3D b){ return (a.X*b.X) + (a.Y*b.Y) + (a.Z*b.Z); }
float Util::length(Point3D p){
return ((p.X*p.X) + (p.Y*p.Y) + (p.Z*p.Z));
}
Point3D Util::cross(Point3D a, Point3D b){
return{ ((a.Y*b.Z) - (a.Z*b.Y)), ((a.X*b.Z) - (a.Z*b.X)), ((a.X*b.Y) - (a.Y*b.X)) };
}
Point3D Util::sub(Point3D a, Point3D b){
return{ a.X - b.X, a.Y - b.Y, a.Z - b.Z };
}
Point3D Util::toBarycentric(Point3D a, Point3D b, Point3D c, Point3D p){
Point3D v0 = sub(c, a);
Point3D v1 = sub(b, a);
Point3D v2 = sub(p, a);

Point3D v12 = cross(v1, v2);
Point3D v10 = cross(v1, v0);

if (dot(v12, v10) < 0){ return{ 0, 0, -1 }; }

Point3D v02 = cross(v0, v2);
Point3D v01 = cross(v0, v1);

if (dot(v02, v01) < 0){ return{ 0, 0, -1 }; }

float denom = length(v01);
return{ length(v12) / denom, length(v02) / denom, 0 };
}

物理函数.cpp

#include "PhysicsHandler.h"
bool Physics::PolyPointCollision(Point3D a,Point3D b,Point3D c,Point3D p){
Point3D w = Util::toBarycentric(a, b, c, p);
if (w.X+w.Y<=1&&w.Z>=0){
return true;
}
return false;
}

最顶层的函数:

bool D3DHandler::IsCollidingWithTerrain(D3DXVECTOR3 pos){
Point3D pointPos = { pos.x, pos.y, pos.z };
for (unsigned int i = 1; i < chunk.at(0).GetWidth() - 1; i++){
for (unsigned int ii = 1; ii < chunk.at(0).GetWidth() - 1; ii++){
Point3D originVertex = chunk.at(0).GetVertex(i, ii);
if (Physics::PolyPointCollision(originVertex,chunk.at(0).GetVertex(i + 1, ii),
chunk.at(0).GetVertex(i, ii + 1),pointPos)){
return true;
}
if (Physics::PolyPointCollision(originVertex,chunk.at(0).GetVertex(i - 1, ii),
chunk.at(0).GetVertex(i, ii - 1),pointPos)){
return true;
}
}
}
return false;
}

证明/测试结果: http://imgur.com/a/HH2pp

关于c++ - 3D 重心点交点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22290427/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com