通过fov计算三维坐标转二维坐标

随手搓的一些代码,部分参考了其他人的代码,有改动,将就看,主要是写给自己的

主要原理是通过鼠标所在的坐标CursorAngle_x和ReadCursorAngle_y,以及自己和敌人的坐标通过一系列数学运算计算出屏幕上的二维坐标。

代码所引用的游戏是cs1.6(OpenGL)

内容不严谨,大佬勿喷。

#include<iostream>
#include<fstream>
#include<windows.h>
#include<string>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include<vector>
#include <tchar.h>
#include <tlhelp32.h>
using namespace std;
#define TOP_HEIGHT 25
#define PI (4.0*atan(1.0))
DWORD __ADR_cstrike_base = 0x1400000;					//用来存储cstrike.exe的地址		
RECT  g_winRect = { 0 };					//定义的一个矩形结构,存储窗口大小
HANDLE g_hProcess;
float viewMatrix[4][4];

	template <class T>
T read(uintptr_t address) {
	T t;
	ReadProcessMemory(g_hProcess, (LPCVOID)address, &t, sizeof t, nullptr);
	return t;
}

template <typename T>
void read_list(uintptr_t address, T* t, SIZE_T count) {
	ReadProcessMemory(g_hProcess, (LPCVOID)address, t, count * (sizeof T), nullptr);
}

template <typename T>//T 是缓冲区(value)
void read_chain(uintptr_t address, vector<uintptr_t>vec, T& out) {				//偏移
	for (int i = 0; i < vec.size(); i++)
	{
		if (i + 1 == vec.size()) {
			out = read<T>(address + vec[i]);
		}
		else {
			address = read<int>(address + vec[i]);
		}
	}
}

void ReadCursorAngle(_Out_ float* CursorAngle_X, _Out_ float* CursorAngle_Y)
{
	ReadProcessMemory(g_hProcess, (PBYTE*)(__ADR_cstrike_base + 0x19E10C8), CursorAngle_X, sizeof(CursorAngle_X), 0);
	ReadProcessMemory(g_hProcess, (PBYTE*)(__ADR_cstrike_base + 0x19E10C4), CursorAngle_Y, sizeof(CursorAngle_Y), 0);
}




BOOL WordToScreen(float EL[3], float MY[3], float to[2])  //过时了
{
	float Arfa, Beta, l, h;
	float CursorAngle_X, CursorAngle_Y;

	//以自己为坐标原点建立坐标系,其他人在这个坐标系中的坐标
	float singned_dx = EL[0] - MY[0];
	float singned_dy = EL[1] - MY[1];
	float singned_dz = EL[2] - MY[2];

	ReadCursorAngle(_Out_ & CursorAngle_X, _Out_ & CursorAngle_Y);

	//x 屏幕上横坐标的计算
	Arfa = atan2(singned_dy, singned_dx);
	Beta = (PI / 180) * CursorAngle_X - Arfa;

	h = 2 * sqrt(singned_dy * singned_dy + singned_dx * singned_dx) * cos(Beta) * tan(PI / 4);
	l = 0.5 * h + sqrt(singned_dy * singned_dy + singned_dx * singned_dx) * sin(Beta);

	//去镜像处理
	if ((CursorAngle_X < ((Arfa * (180 / PI)) - 45) || CursorAngle_X >((Arfa * (180 / PI)) + 45)) && (CursorAngle_X < ((Arfa * (180 / PI)) + 360 - 45) || CursorAngle_X >((Arfa * (180 / PI)) + 360 + 45)))
	{
		return FALSE;
	}

	to[0] = l / h * (g_winRect.right - g_winRect.left);

	//y 屏幕上纵坐标的计算
	Arfa = atan2(singned_dz, sqrt(singned_dy * singned_dy + singned_dx * singned_dx));
	Beta = (PI / 180) * (-1 * CursorAngle_Y) - Arfa;

	h = 2 * sqrt(pow((double)singned_dx, 2.0) + pow((double)singned_dy, 2.0) + pow((double)singned_dz, 2.0)) * cos(Beta) * tan(PI / 6);
	l = 0.5 * h + sqrt(pow((double)singned_dx, 2.0) + pow((double)singned_dy, 2.0) + pow((double)singned_dz, 2.0)) * sin(Beta);

	to[1] = l / h * (g_winRect.bottom - g_winRect.top);


	return TRUE;
}

void GetXYDistance(float EL[3], float MY[3], float* XYDistance)
{
	float EnemyXY[2];
	WordToScreen(EL, MY, EnemyXY);
	//在屏幕内
	if ((EnemyXY[0] > 0 && EnemyXY[0] < g_winRect.right - g_winRect.left) &&
		(EnemyXY[1] > 0 && EnemyXY[1] < g_winRect.bottom - g_winRect.top))
	{

		*XYDistance = fabs(EnemyXY[0] - ((g_winRect.right - g_winRect.left) / 2)) +
			fabs(EnemyXY[1] - ((g_winRect.bottom - g_winRect.top) / 2));
	}
	else
	{
		*XYDistance = 999999.0f;
	}
}

//获取坐标函数
void readcoodinate(float EL[3],float MY[3]) {
	vector<uintptr_t>vec  = { 0x011069BC,0x3AC };
	vector<uintptr_t>vec1 = { 0x011069BC, 0x3B0 };
	vector<uintptr_t>vec2 = { 0x011069BC, 0x3B4 };
	read_chain(__ADR_cstrike_base , vec, EL[0]);
	read_chain(__ADR_cstrike_base , vec1, EL[1]);
	read_chain(__ADR_cstrike_base , vec2, EL[2]);
	vector<uintptr_t>vec4  = { 0x011069BC,0x88 };
	vector<uintptr_t>vec5 = { 0x011069BC, 0x8c };
	vector<uintptr_t>vec6 = { 0x011069BC, 0x90 };
	read_chain(__ADR_cstrike_base , vec4, MY[0]);
	read_chain(__ADR_cstrike_base , vec5, MY[1]);
	read_chain(__ADR_cstrike_base , vec6, MY[2]);
	/*cout << EL[0] << endl;
	cout << EL[1] << endl;
	cout << EL[2] << endl;
	cout << MY[0] << endl;
	cout << MY[1] << endl;
	cout << MY[2] << endl;*/
}





int main()
{
	HWND hWnd = FindWindow(NULL, "Counter-Strike");			//判断游戏是否打开,获取游戏进程句柄
	DWORD process_ID;   //进程
	DWORD thread_ID=GetWindowThreadProcessId(hWnd, &process_ID);
	g_hProcess = OpenProcess(PROCESS_ALL_ACCESS, TRUE, process_ID);//进程句柄
	cout << g_hProcess << endl;
	float EL[3],MY[3],to[2];
	::GetWindowRect(hWnd, &g_winRect);														//获取窗口大小
	g_winRect.top += TOP_HEIGHT;
	while(1){
	system("cls");
	readcoodinate(EL, MY);
	WorldToScreen(EL,MY,to);
	cout << to[0] << endl;
	cout << to[1] << endl;
	Sleep(20);
	}
	system("pause");
	return 0;
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值