四叉树碰撞代码

使用raylib

代码来源

https://github.com/seyhajin/flux-samples/blob/master/raylib/quadtree/quadtree.c

原来是视锥碰撞四叉树,经过一周开发变成碰撞检测四叉树可视化

后经过改写

绿色检测

灰色检测

//https://github.com/seyhajin/flux-samples/blob/master/raylib/quadtree/quadtree.c/*********************************************************************************************   raylib: quadtree (adapted for HTML5 platform)**   This example is prepared to compile for PLATFORM_WEB, PLATFORM_DESKTOP and PLATFORM_RPI*   As you will notice, code structure is slightly diferent to the other examples...*   To compile it for PLATFORM_WEB just uncomment #define PLATFORM_WEB at beginning**   This example has been created using raylib 3.7 (www.raylib.com)*   raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)**   Copyright (c) 2015 Ramon Santamaria (@raysan5)*   Copyright (c) 2021 Christophe TES (@seyhajin)*********************************************************************************************/#include <stdio.h>
#include <math.h>#include "raylib.h"
#include "raymath.h"//----------------------------------------------------------------------------------
// Types and Structures Definition
//----------------------------------------------------------------------------------//----- Frustumstatic Vector2 fl, fr; // left/right planes//----- Cameratypedef struct camera_s {Vector2 pos;float fov;int num;			// 记录编号,解决自己碰撞自己问题
} camera_t;camera_t create_camera(float x, float y, float fov) {return (camera_t) {.pos = (Vector2) {x, y},.fov = fov};
}typedef struct target {int targeti;int targetj;int targetwidth;int targetheight;RenderTexture2D pic;
//	RenderTexture* pic;target* linknext;				// 这是四叉树里增加敌人,发现要增加好几个敌人时,追加在敌人后面,最简单修改就是增加一行,于是反过来修改敌人数据int number;						// 记录敌人编号int islive;
} target;//----- Quadtreetypedef enum quad_child_e {CHILD_TL, // top-leftCHILD_BL, // bottom-leftCHILD_BR, // bottom-rightCHILD_TR, // top-rightCHILD_COUNT
} quad_child_t;typedef struct quadtree_s {Vector2 min;Vector2 max;struct quadtree_s *childs[CHILD_COUNT];target* enemy;									// 绑定的数据
} quadtree_t;quadtree_t *create_quadtree(float xmin, float ymin, float xmax, float ymax, int depth) {quadtree_t *qt = (quadtree_t*)MemAlloc(sizeof(quadtree_t));qt->min = (Vector2) {xmin, ymin};qt->max = (Vector2) {xmax, ymax};// 追加空记录qt->enemy = NULL;if (depth > 0) {float xavg = (xmin + xmax) * 0.5f;float yavg = (ymin + ymax) * 0.5f;depth--;qt->childs[CHILD_TL] = create_quadtree(xmin, ymin, xavg, yavg, depth);qt->childs[CHILD_BL] = create_quadtree(xmin, yavg, xavg, ymax, depth);qt->childs[CHILD_BR] = create_quadtree(xavg, yavg, xmax, ymax, depth);qt->childs[CHILD_TR] = create_quadtree(xavg, ymin, xmax, yavg, depth);}return qt;
}void free_quadtree(quadtree_t *qt) {for (int i = 0; i < CHILD_COUNT; i++)MemFree(qt->childs[i]);MemFree(qt);
}int check(quadtree_t* qt, camera_t cam) {if (cam.pos.x > qt->min.x && cam.pos.x < qt->max.x && cam.pos.y > qt->min.y && cam.pos.y < qt->max.y) {return 1;}// 不加return 0 不出格子return 0;
}// 修改为查找数据并记录
void render_quadtree(quadtree_t *qt, camera_t cam, int depth) {if (check(qt, cam)) {if (qt->enemy == NULL) {qt->enemy = new target;qt->enemy->targetj = cam.pos.x;qt->enemy->targeti = cam.pos.y;qt->enemy->number = cam.num;} else if (qt->enemy->number == -1) {qt->enemy->targetj = cam.pos.x;qt->enemy->targeti = cam.pos.y;qt->enemy->number = cam.num;}//		printf("%d\n", qt->enemy->number);if (depth > 1) {float xavg = (qt->min.x + qt->max.x) * 0.5f;float yavg = (qt->min.y + qt->max.y) * 0.5f;
//			DrawLine(xavg, qt->min.y, xavg, qt->max.y, GRAY);DrawLine(xavg, qt->min.y, xavg, qt->max.y, GREEN);
//			DrawLine(qt->min.x, yavg, qt->max.x, yavg, GRAY);DrawLine(qt->min.x, yavg, qt->max.x, yavg, GREEN);// 记录本层区域有敌人depth--;render_quadtree(qt->childs[CHILD_TL], cam, depth);render_quadtree(qt->childs[CHILD_BL], cam, depth);render_quadtree(qt->childs[CHILD_BR], cam, depth);render_quadtree(qt->childs[CHILD_TR], cam, depth);}}
}// 修改为查找数据并记录为已标记为“无” -1 表示没有敌人
// 修改自刚刚实现的查找记录功能数据void render_quadtreev3_delete(quadtree_t *qt, camera_t cam, int depth) {// 注释check 后清空数据未果if (check(qt, cam)) {if (qt->enemy == NULL) {qt->enemy = new target;}qt->enemy->targetj = -1;qt->enemy->targeti = -1;qt->enemy->number = -1;if (depth > 1) {float xavg = (qt->min.x + qt->max.x) * 0.5f;float yavg = (qt->min.y + qt->max.y) * 0.5f;// 记录本层区域有敌人depth--;// 注释掉render_quadtree 发现报错,原来是没有改旧函数导致直接重新标记 -_-|render_quadtreev3_delete(qt->childs[CHILD_TL], cam, depth);render_quadtreev3_delete(qt->childs[CHILD_BL], cam, depth);render_quadtreev3_delete(qt->childs[CHILD_BR], cam, depth);render_quadtreev3_delete(qt->childs[CHILD_TR], cam, depth);}}
}// 检测最小一个格子检测
// 追加返回值
//void render_quadtreev4_only_one(quadtree_t *qt, camera_t cam, int depth) {
int render_quadtreev4_only_one(quadtree_t *qt, camera_t cam, int depth) {// 原来禁用check可以打印全部记录数据// 这是对比12.绑定敌人数据与四叉树 对应名称的代码得知的// 不禁用,就是开始检测碰撞// 追加检测碰撞if (check(qt, cam)) {if (depth > 1) {float xavg = (qt->min.x + qt->max.x) * 0.5f;float yavg = (qt->min.y + qt->max.y) * 0.5f;DrawLine(xavg, qt->min.y, xavg, qt->max.y, GRAY);DrawLine(qt->min.x, yavg, qt->max.x, yavg, GRAY);// 先检测空if (qt->enemy != NULL) {if (cam.num != qt->enemy->number && qt->enemy->number != -1) {depth--;int a = 0;a += render_quadtreev4_only_one(qt->childs[CHILD_TL], cam, depth);if (a > 0) {return 1;}a += render_quadtreev4_only_one(qt->childs[CHILD_BL], cam, depth);if (a > 0) {return 1;}a += render_quadtreev4_only_one(qt->childs[CHILD_BR], cam, depth);if (a > 0) {return 1;}a += render_quadtreev4_only_one(qt->childs[CHILD_TR], cam, depth);if (a > 0) {return 1;}}}} else {// 最小格子记录// v4_only_one 绘制颜色仅绘制一格if (qt->enemy != NULL) {if (qt->enemy->number != cam.num && qt->enemy->number != -1) {
//					printf("%d\n",qt->enemy->number);
//					if (cam.pos.x > qt->enemy->targetj && cam.pos.x <  qt->enemy->targetj + 30 && cam.pos.y > qt->enemy->targeti && cam.pos.y < qt->enemy->targeti + 30 ) {
//					if (cam.pos.x > qt->enemy->targetj && cam.pos.x <  qt->enemy->targetj + 130 && cam.pos.y > qt->enemy->targeti && cam.pos.y < qt->enemy->targeti + 130 ) {
//					if (cam.pos.x > qt->enemy->targetj-10 && cam.pos.x <  qt->enemy->targetj + 130 && cam.pos.y > qt->enemy->targeti-10 && cam.pos.y < qt->enemy->targeti + 130 ) {
//					if (cam.pos.x >= qt->enemy->targetj && cam.pos.x <  qt->enemy->targetj + 130 && cam.pos.y >= qt->enemy->targeti && cam.pos.y < qt->enemy->targeti + 130 ) {
//					if ( cam.pos.x <  qt->enemy->targetj + 130  && cam.pos.y < qt->enemy->targeti + 130 ) {
//					if ( cam.pos.x <  qt->enemy->targetj + 100  && cam.pos.y < qt->enemy->targeti + 100 ) {
//					if ( cam.pos.x <  qt->enemy->targetj + 10  && cam.pos.y < qt->enemy->targeti + 10 ) {// 复制粘贴自47.发现实现碰撞检测
//					if (cam.pos.x > qt->enemy->targetj + 1 && cam.pos.x < qt->enemy->targetj + 10 && cam.pos.y + 1 > qt->enemy->targeti && cam.pos.y < qt->enemy->targeti + 10) {// 自100 进行对照移植
//					if (cam.pos.x > qt->enemy->targetj + 1 && cam.pos.x < qt->enemy->targetj + 10 && cam.pos.y + 1 > qt->enemy->targeti && cam.pos.y < qt->enemy->targeti + 10) {
//					if (cam.pos.x > qt->enemy->targetj && cam.pos.x < qt->enemy->targetj + 10 && cam.pos.y+1 > qt->enemy->targeti && cam.pos.y < qt->enemy->targeti + 10) {if (qt->enemy->number != cam.num && qt->enemy->number != -1) {printf("%d\n", qt->enemy->number);
// 测试之后,反而是黑色比红色准确
//						DrawRectangle(qt->min.x, qt->min.y, qt->max.x - qt->min.x, qt->max.y - qt->min.y, RED);DrawRectangle(qt->enemy->targetj, qt->enemy->targeti, 10, 10, BLUE);return 1; // 碰撞上了}
//					DrawRectangle(qt->enemy->targetj, qt->enemy->targeti, 100, 100,BLUE);}}}}// 没有碰撞就返回0return 0;
}//----------------------------------------------------------------------------------
// Global Variables Definition
//----------------------------------------------------------------------------------
static int screen_width = 1012;
static int screen_height = 1012;// Quadtree
static int quad_depth = 8; // depth
static int quad_size = 1012; // size
static quadtree_t *root;// Camera
static float cam_speed = 2; // speed
static float cam_fov = 60.0f; // field of view
static float view_line = 300; // frustum plane
static camera_t camera;//int enemysum = 100;
int enemysum = 10;
target* enemy;//----------------------------------------------------------------------------------
// Module Functions Declaration
//----------------------------------------------------------------------------------
void UpdateDrawFrame(void);     // Update and Draw one frame//----------------------------------------------------------------------------------
// Main Enry Point
//----------------------------------------------------------------------------------
int main() {// Initialization//--------------------------------------------------------------------------------------InitWindow(screen_width, screen_height, "raylib: quadtree");// Create camera & quadtreefl = Vector2Zero();fr = Vector2Zero();camera = create_camera(quad_size / 2, quad_size / 2, cam_fov);root = create_quadtree(0, 0, quad_size, quad_size, quad_depth);SetTargetFPS(60);   // Set our game to run at 60 frames-per-second//--------------------------------------------------------------------------------------target* enemyv2 = new target[enemysum];for (int n = 0; n < enemysum; n++) {enemyv2[n].targetj = rand() % 1000;enemyv2[n].targeti = rand() % 1000;enemyv2[n].targetwidth = rand() % 100;enemyv2[n].targetheight = rand() % 200;enemyv2[n].pic = LoadRenderTexture(enemyv2[n].targetwidth, enemyv2[n].targetheight);enemyv2[n].islive = 1;enemyv2[n].number = n;printf("%d %d\n", enemyv2[n].targetj, enemyv2[n].targeti);}enemy = enemyv2;for (int n = 0; n < enemysum; n++) {BeginTextureMode(enemy[n].pic);for (int i = 0; i < enemy[n].targetheight; i++) {for (int j = 0; j < enemy[n].targetwidth; j++) {DrawPixel(j, i, {n * 20 % 255, n * 20 % 255, n * 20 % 255 % 255, 255});}}EndTextureMode();}// Main game loopwhile (!WindowShouldClose()) {  // Detect window close button or ESC keyUpdateDrawFrame();}// De-Initializationfree_quadtree(root);//--------------------------------------------------------------------------------------CloseWindow();        // Close window and OpenGL context//--------------------------------------------------------------------------------------return 0;
}//----------------------------------------------------------------------------------
// Module Functions Definition
//----------------------------------------------------------------------------------
void UpdateDrawFrame(void) {// Update//----------------------------------------------------------------------------------// TODO: Update your variables here//----------------------------------------------------------------------------------//Vector2 mouse_pos = GetMousePosition();// update camera positionif (IsKeyDown(KEY_LEFT)) {camera.pos.x -= cam_speed;} else if (IsKeyDown(KEY_RIGHT)) {camera.pos.x += cam_speed;}if (IsKeyDown(KEY_UP)) {camera.pos.y -= cam_speed;} else if (IsKeyDown(KEY_DOWN)) {camera.pos.y += cam_speed;}// camera anglefloat px = (float)GetMouseX() - camera.pos.x;float py = (float)GetMouseY() - camera.pos.y;float angle = atan2f(py, px);float cam_fov_rad = (camera.fov / 2.0f) * DEG2RAD;Vector2 cam_dir = (Vector2) {.x = camera.pos.x + (view_line * 0.5f) * cosf(angle),.y = camera.pos.y + (view_line * 0.5f) * sinf(angle)};// update frustum left positionfl.x = camera.pos.x + view_line * cosf(angle - cam_fov_rad);fl.y = camera.pos.y + view_line * sinf(angle - cam_fov_rad);// update frustum right positionfr.x = camera.pos.x + view_line * cosf(angle + cam_fov_rad);fr.y = camera.pos.y + view_line * sinf(angle + cam_fov_rad);// Draw//----------------------------------------------------------------------------------BeginDrawing();ClearBackground(WHITE);// 记录旧数据static camera_t oldcamera;// draw quadtreefor (int n = 0; n < enemysum; n++) {
//			不能相同名称的 static, 原来版本仅有一个static camera_t b 所以能跑
//			static camera_t b;camera_t b;// 测试半天,发现没有加入标号b.num = enemy[n].number;for (int i = 0; i < enemy[n].targetheight ; i++) {b.pos.x = enemy[n].targetj + 0;b.pos.y = enemy[n].targeti + i;render_quadtree(root, b, quad_depth);}for (int i = 0; i < enemy[n].targetheight ; i++) {b.pos.x = enemy[n].targetj + enemy[n].targetwidth;b.pos.y = enemy[n].targeti + i;render_quadtree(root, b, quad_depth);}for (int j = 0; j < enemy[n].targetwidth ; j++) {b.pos.x = enemy[n].targetj + j;b.pos.y = enemy[n].targeti + 0;render_quadtree(root, b, quad_depth);}for (int j = 0; j < enemy[n].targetwidth ; j++) {b.pos.x = enemy[n].targetj + j;b.pos.y = enemy[n].targeti + enemy[n].targetheight ;render_quadtree(root, b, quad_depth);}}int playerj = camera.pos.x;int playeri = camera.pos.y;// 测试碰撞敌群for (int n = 0; n < enemysum; n++) {// 一个点camera_t b;// 自100追加numb.num = enemy[n].number;int a = 0;for (int i = 0; i < enemy[n].targetheight ; i ++) {b.pos.x = enemy[n].targetj + 0;b.pos.y = enemy[n].targeti + i;a += render_quadtreev4_only_one(root, b, quad_depth);if (a > 0) {break;}}for (int i = 0; i < enemy[n].targetheight ; i ++) {b.pos.x = enemy[n].targetj + enemy[n].targetwidth - 1;b.pos.y = enemy[n].targeti + i;a += render_quadtreev4_only_one(root, b, quad_depth);if (a > 0) {break;}}for (int j = 0; j < enemy[n].targetwidth ; j ++) {b.pos.x = enemy[n].targetj + j;b.pos.y = enemy[n].targeti + 0;a += render_quadtreev4_only_one(root, b, quad_depth);if (a > 0) {break;}}for (int j = 0; j < enemy[n].targetwidth ; j ++) {b.pos.x = enemy[n].targetj + j;b.pos.y = enemy[n].targeti + enemy[n].targetheight - 1 ;a += render_quadtreev4_only_one(root, b, quad_depth);if (a > 0) {break;}}// 随机倒退,减少重叠if (a > 0) {if (enemy[n].islive == 1) {if (enemy[n].targetj < playerj) {
//						enemy[n].targetj += -1 - rand() % 30;enemy[n].targetj += -1 - rand() % 10;} else if (enemy[n].targetj > playerj) {
//						enemy[n].targetj -= -1 - rand() % 30;enemy[n].targetj -= -1 - rand() % 10;}if (enemy[n].targeti > playeri) {
//						enemy[n].targeti -= -1 - rand() % 30;enemy[n].targeti -= -1 - rand() % 10;} else if (enemy[n].targeti < playeri) {
//						enemy[n].targeti += -1 - rand() % 30;enemy[n].targeti += -1 - rand() % 10;}}}}// 启用成功,没有旧标记了// 改颜色禁用测试碰撞效果// 删除旧数据,在敌人移动之前for (int n = 0; n < enemysum; n++) {camera_t b;// 测试批量网格// 自100追加numb.num = enemy[n].number;// 在发现进检测周围一周格子,于是原样删除,就仅删除四周一环格子,for (int i = 0; i < enemy[n].targetheight ; i++) {b.pos.x = enemy[n].targetj + 0;b.pos.y = enemy[n].targeti + i;render_quadtreev3_delete(root, b, quad_depth);}for (int i = 0; i < enemy[n].targetheight ; i++) {b.pos.x = enemy[n].targetj + enemy[n].targetwidth;b.pos.y = enemy[n].targeti + i;render_quadtreev3_delete(root, b, quad_depth);}for (int j = 0; j < enemy[n].targetwidth ; j++) {b.pos.x = enemy[n].targetj + j;b.pos.y = enemy[n].targeti + 0;render_quadtreev3_delete(root, b, quad_depth);}for (int j = 0; j < enemy[n].targetwidth ; j++) {b.pos.x = enemy[n].targetj + j;b.pos.y = enemy[n].targeti + enemy[n].targetheight ;render_quadtreev3_delete(root, b, quad_depth);}}DrawRectangleLines(root->min.x, root->min.y, root->max.x - root->min.x, root->max.y - root->min.y, RED);// 绘制敌人for (int n = 0; n < enemysum; n++) {DrawTexturePro(enemy[n].pic.texture,{0, 0, enemy[n].targetwidth, enemy[n].targetheight},{enemy[n].targetj, enemy[n].targeti, enemy[n].targetwidth, enemy[n].targetheight},{0, 0}, 0, WHITE);}// 敌人移动for (int n = 0; n < enemysum; n++) {if (enemy[n].islive == 1) {if (enemy[n].targetj < playerj) {enemy[n].targetj += 1;} else if (enemy[n].targetj > playerj) {enemy[n].targetj -= 1;}if (enemy[n].targeti > playeri) {enemy[n].targeti -= 1;} else if (enemy[n].targeti < playeri) {enemy[n].targeti += 1;}}}// draw frustum left planeDrawLine(camera.pos.x, camera.pos.y, fl.x, fl.y, GREEN);// draw frustum right planeDrawLine(camera.pos.x, camera.pos.y, fr.x, fr.y, RED);//  draw cameraDrawLine(camera.pos.x, camera.pos.y, cam_dir.x, cam_dir.y, YELLOW);DrawCircle(camera.pos.x, camera.pos.y, 10, BLUE);// draw texts//DrawText(TextFormat("mouse.pos: (%f, %f)", px, py), 0, 0, 20, DARKGRAY);//DrawText(TextFormat("camera.pos: (%f, %f)", camera.pos.x, camera.pos.y), 0, 25, 20, DARKGRAY);DrawText(TextFormat("FPS %d", GetFPS()), 0, 0, 30, BLACK);EndDrawing();//----------------------------------------------------------------------------------
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/147678.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

【C++篇】走进C++标准模板库:STL的奥秘与编程效率提升之道

文章目录 C STL 初探&#xff1a;打开标准模板库的大门前言第一章: 什么是STL&#xff1f;1.1 标准模板库简介1.2 STL的历史背景1.3 STL的组成 第二章: STL的版本与演进2.1 不同的STL版本2.2 STL的影响与重要性 第三章: 为什么学习 STL&#xff1f;3.1 从手动编写到标准化解决方…

three.js 让阴影更黑更暗

r166 可以通过设置intensity属性来配置每个光源的阴影强度 light.shadow.intensity 3;或者 修改shader THREE.ShaderChunk["shadowmap_pars_fragment"]THREE.ShaderChunk["shadowmap_pars_fragment"].replace( "occlusion clamp( max( hard_sha…

基于深度学习的药品三期OCR字符识别

在药品生产线上,药品三期的喷码与条形码识别是保证药品追溯和安全管理的重要环节。传统的识别方法依赖于人工操作,不仅效率低下且容易出错。随着深度学习技术的不断发展,基于OCR(Optical Character Recognition,光学字符识别)的自动化识别系统逐渐成为主流。本文将以哪吒…

计算机前沿技术-人工智能算法-大语言模型-最新论文阅读-2024-09-17

计算机前沿技术-人工智能算法-大语言模型-最新论文阅读-2024-09-17 1. Large Language Models in Biomedical and Health Informatics: A Review with Bibliometric Analysis H Yu, L Fan, L Li, J Zhou, Z Ma, L Xian, W Hua, S He… - Journal of Healthcare …, 2024 生物…

中国雕塑—孙溟展浅析碑帖《郑文公碑》

中国雕塑——孙溟展浅析碑帖《郑文公碑》 《郑文公碑》上碑 《郑文公碑》 下碑 《郑文公碑》是北魏摩崖刻石&#xff0c;又称是《郑羲碑》&#xff0c;属楷书体&#xff0c;此碑分两块&#xff0c;在山东平度县天柱山的那块称之为“上碑”&#xff0c;上碑全称《魏故中书令秘书…

ONNX模型部署利器ONNXRUNTIME框架

1.ONNXRUNTIME介绍 ONNX格式模型部署兼容性最强的框架 ONNXRUNTIME&#xff0c;基本上不会有算子不支持跟不兼容的情况出现&#xff0c;只要能导出ONNX格式模型&#xff0c;它基本上都能成功加载&#xff0c;成功推理。虽然在CPU速度不及OpenVINO、GPU上速度不及TensorRT&#…

RK3588NPU驱动版本升级至0.9.6教程

RK3588NPU驱动版本升级至0.9.6教程 1、下载RK3588NPU驱动2、修改NPU驱动源码2.0 修改MONITOR_TPYE_DEV写错问题2.1 解决缺少函数rockchip_uninit_opp_table问题2.2 解决缺少函数vm_flags_set、vm_flag_clear的问题2.3 内核编译成功2.4 重新构建系统 3、注意事项4、其他问题处理…

智谱清影的魅力:使用CogVideoX-2b生成6秒视频的真实体验!

文章目录 1 3D变分自编码器与3D RoPE2 精确描述与多样化输入3 社区的力量与未来展望 在8月6日&#xff0c;智谱 AI 发布了一则令人振奋的消息&#xff1a;他们决定开源其视频生成模型CogVideoX。 1 3D变分自编码器与3D RoPE 作为一名开发者&#xff0c;我近期才来体验这个新工…

【C++】面向对象编程的三大特性:深入解析继承机制

C语法相关知识点可以通过点击以下链接进行学习一起加油&#xff01;命名空间缺省参数与函数重载C相关特性类和对象-上篇类和对象-中篇类和对象-下篇日期类C/C内存管理模板初阶String使用String模拟实现Vector使用及其模拟实现List使用及其模拟实现容器适配器Stack与QueuePriori…

关闭小广告【JavaScript】

在 JavaScript 中实现关闭小广告的功能&#xff0c;可以通过监听点击事件来隐藏广告元素。 实现效果&#xff1a; 代码&#xff1a; <!DOCTYPE html> <html lang"zh"><head><meta charset"UTF-8"><meta name"viewport&q…

IP地址免费SSL证书建议使用吗?

IP地址免费SSL证书的现状 市场情况&#xff1a;目前市面上并没有免费的IP地址SSL证书。即使有少数机构提供所谓的“免费”证书&#xff0c;也可能存在功能限制、有效期短、技术支持不足等问题。 提供机构&#xff1a;尽管没有完全的免费选项&#xff0c;但可以选择一些可信赖的…

基于51单片机的简易8层电梯模拟proteus仿真

地址&#xff1a;https://pan.baidu.com/s/1z4SBpi2yb8Qeu-85jqkuZQ 提取码&#xff1a;1234 仿真图&#xff1a; 芯片/模块的特点&#xff1a; AT89C52/AT89C51简介&#xff1a; AT89C52/AT89C51是一款经典的8位单片机&#xff0c;是意法半导体&#xff08;STMicroelectron…

实用为主,需求为王!通风天窗专业厂家谈谈通风天窗怎么选?

通风天窗作为现代建筑的重要组成部分&#xff0c;不仅能够有效改善室内空气质量&#xff0c;还能增强建筑的自然采光与美观性。市场上通风天窗种类繁多&#xff0c;品质参差不齐&#xff0c;如何选购一款既满足功能需求又性价比高的产品&#xff0c;成为业主关注的焦点。成都昱…

图为科技大模型一体机,智领未来社区服务

当AI与边缘计算相遇&#xff0c;一幅关于智慧生活的宏伟蓝图正缓缓展开。 今天&#xff0c;让我们一同探索&#xff0c;如何通过图为大模型一体机&#xff0c;为物业服务插上智能的翅膀。 通过整合采集物业数据&#xff0c;大模型一体机可全方位为物业行业赋能&#xff0c;实…

【SpringBoot详细教程】-02-SpringBoot配置【持续更新】

Hello&#xff01;彦祖们&#xff0c;从今天开始我将更新一波超详细的SpringBoot的图文教程&#xff0c;感兴趣的老铁给个关注点赞 支持一下呗&#xff0c;最好再评论一个666&#xff0c;O(∩_∩)O哈哈~&#xff08;贪心了&#xff09; 点个关注吧 02. SpringBoot配置 Sprin…

图像放大效果示例【JavaScript】

实现效果&#xff1a; 当鼠标悬停在小图&#xff08;缩略图&#xff09;上时&#xff0c;大图&#xff08;预览图&#xff09;会随之更新为相应的小图&#xff0c;并高亮当前悬浮的小图的父元素。 代码&#xff1a; 1. HTML部分 <!DOCTYPE html> <html lang"z…

[Excel VBA]如何使用VBA自动生成图表

在Excel中&#xff0c;图表是可视化数据的重要工具。以下是一个VBA代码示例&#xff0c;帮助你自动生成图表。 1. 代码说明 该代码会根据指定数据范围创建一个柱状图&#xff0c;并设置图表的基本属性。 2. VBA代码 Sub CreateChart()Dim ws As WorksheetDim chartObj As Ch…

转行要趁早!网络安全岗人才稀缺,前景广阔,零基础入门到精通,收藏这篇就够了

1 网络安全从业人员能力基本要求&#xff0c;您达标了吗&#xff1f; 引导 根据国家市场监督管理总局、国家标准化管理委员会发布中华人民共和国国家标准公告&#xff08;2023年第1号&#xff09;&#xff0c;由全国信息安全标准化技术委员会归口的《信息安全技术 网络安全从业…

考题抄错会做也白搭——模板方法模式

文章目录 考题抄错会做也白搭——模板方法模式选择题不会做&#xff0c;蒙呗&#xff01;重复易错难改提炼代码模板方法模式模板方法模式的特点 考题抄错会做也白搭——模板方法模式 选择题不会做&#xff0c;蒙呗&#xff01; 时间&#xff1a;3月27日19点  地点&#xff…

【C++】智能指针模拟实现及详解

目录 什么是智能指针&#xff1a; 为什么要有智能指针&#xff1a; auto_ptr: unique_ptr&#xff1a; shared_ptr&#xff1a; shared_ptr的缺陷&#xff1a; weak_ptr: 什么是智能指针&#xff1a; 概念&#xff1a; 智能指针是一种特殊的类模板&#xff0c;用于自动…