首页 > 其他分享 >雷达效果

雷达效果

时间:2024-05-06 21:55:45浏览次数:22  
标签:p2 p1 效果 hull double 雷达 copy Point3D

相位阵雷达效果

一个简单思路:
在一个扇形范围内,用多个射线检测来每tick判断

点击查看代码
#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Components/SphereComponent.h"
#include "MyActor.generated.h"

UCLASS()
class TEST_API AMyActor : public AActor
{
	GENERATED_BODY()
	
public:	
	// Sets default values for this actor's properties
	AMyActor();
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Detection Settings")
		float HorizontalDetectionAngle;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Detection Settings")
		float VerticalDetectionAngle;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Detection Settings")
		float RaycastAngleIncrement;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Detection Settings")
		float RaycastLength;

	UFUNCTION(BlueprintCallable,Category = "Detection")
	TArray<AActor*> PerformRaycastDetection();

	UPROPERTY(EditAnywhere ,BlueprintReadWrite)
		USphereComponent* DetectionSphere;

protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

public:	
	// Called every frame
	virtual void Tick(float DeltaTime) override;

};

// Sets default values
AMyActor::AMyActor()
{
 	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
    PrimaryActorTick.bCanEverTick = false;

    DetectionSphere = CreateDefaultSubobject<USphereComponent>(TEXT("Detection Sphere"));
    RootComponent = DetectionSphere;

    HorizontalDetectionAngle = 45.0f;
    VerticalDetectionAngle = 45.0f;
    RaycastAngleIncrement = 5.0f;
    RaycastLength = 1000.0f;

}

TArray<AActor*> AMyActor::PerformRaycastDetection()
{
    TArray<AActor*> DetectedActors;

    if (!DetectionSphere)
        return DetectedActors;

    FVector StartLocation = DetectionSphere->GetComponentLocation();
    FRotator Rotation = DetectionSphere->GetComponentRotation();

    float HalfHorizontalAngle = HorizontalDetectionAngle * 0.5f;
    float HalfVerticalAngle = VerticalDetectionAngle * 0.5f;
    UE_LOG(LogTemp, Warning,TEXT("HalfHorizontalAngle %f HalfVerticalAngle %f RaycastAngleIncrement %f"), HalfHorizontalAngle, HalfVerticalAngle, RaycastAngleIncrement);

    for (float VerticalAngle = -HalfVerticalAngle; VerticalAngle <= HalfVerticalAngle; VerticalAngle += RaycastAngleIncrement)
    {
        for (float HorizontalAngle = -HalfHorizontalAngle; HorizontalAngle <= HalfHorizontalAngle; HorizontalAngle += RaycastAngleIncrement)
        {
            FRotator RayRotation = Rotation;
            RayRotation.Pitch += VerticalAngle;
            RayRotation.Yaw += HorizontalAngle;

            FVector EndLocation = StartLocation + RayRotation.Vector() * RaycastLength;
            DrawDebugLine(GetWorld(), StartLocation, EndLocation, FColor::Red, false, -1.0f, 0, 2.0f);
            FHitResult HitResult;
            if (GetWorld()->LineTraceSingleByChannel(HitResult, StartLocation, EndLocation, ECC_Visibility))
            {
                AActor* HitActor = HitResult.GetActor();
                if (HitActor)
                {
                    DetectedActors.AddUnique(HitActor);
                }
            }
        }
    }

    return DetectedActors;
}


最后效果

吧drawdebugline换成drawdebugcone

各个参数可调

无人机编队
无人机之间连线

无人机外包洛信息

三维包洛算法
如果要处理三维坐标点的凸包,那么我们需要稍微修改一下算法。基本思路是仍然使用Graham扫描算法,但需要对叉积函数和极角排序方式进行调整。
下面是修改后的C++代码:
cppCopy code#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>

using namespace std;

// 定义三维点的结构体
struct Point3D {
    double x, y, z;
    Point3D(double x, double y, double z) : x(x), y(y), z(z) {}
};

// 叉积计算函数
double crossProduct(const Point3D& p1, const Point3D& p2, const Point3D& p3) {
    double x1 = p2.x - p1.x, y1 = p2.y - p1.y, z1 = p2.z - p1.z;
    double x2 = p3.x - p1.x, y2 = p3.y - p1.y, z2 = p3.z - p1.z;
    return x1 * y2 * z1 - x1 * z2 * y1 - y1 * x2 * z1 + y1 * z2 * x1 + z1 * x2 * y1 - z1 * y2 * x1;
}

// Graham扫描算法实现
vector<Point3D> grahamScan(vector<Point3D>& points) {
    // 找到z坐标最小的点作为起点
    auto start = min_element(points.begin(), points.end(), [](const Point3D& p1, const Point3D& p2) {
        return p1.z < p2.z || (p1.z == p2.z && p1.y < p2.y) || (p1.z == p2.z && p1.y == p2.y && p1.x < p2.x);
    });
    
    // 按极角排序点
    sort(points.begin(), points.end(), [&start](const Point3D& p1, const Point3D& p2) {
        double cross = crossProduct(*start, p1, p2);
        if (cross == 0) {
            double d1 = sqrt((p1.x - start->x) * (p1.x - start->x) + (p1.y - start->y) * (p1.y - start->y) + (p1.z - start->z) * (p1.z - start->z));
            double d2 = sqrt((p2.x - start->x) * (p2.x - start->x) + (p2.y - start->y) * (p2.y - start->y) + (p2.z - start->z) * (p2.z - start->z));
            return d1 < d2;
        }
        return cross > 0;
    });
    
    // 构造凸包
    vector<Point3D> hull;
    for (const Point3D& p : points) {
        while (hull.size() > 1 && crossProduct(hull[hull.size() - 2], hull.back(), p) <= 0) {
            hull.pop_back();
        }
        hull.push_back(p);
    }
    
    return hull;
}

int main() {
    // 假设无人机坐标存储在drones_list中
    vector<vector<Point3D>> drones_list = {
        {Point3D(0, 3, 1), Point3D(1, 1, 2), Point3D(2, 2, 3), Point3D(4, 4, 4), Point3D(0, 0, 0), Point3D(1, 2, 1), Point3D(3, 1, 2), Point3D(3, 3, 3)},
        {Point3D(2, 3, 1), Point3D(4, 1, 2), Point3D(6, 4, 3), Point3D(5, 2, 4), Point3D(3, 0, 0), Point3D(1, 2, 1), Point3D(0, 1, 2)}
    };
    
    vector<vector<Point3D>> convex_hulls;
    for (const auto& drones : drones_list) {
        convex_hulls.push_back(grahamScan(drones));
    }
    
    // 输出结果
    for (const auto& hull : convex_hulls) {
        cout << "Convex Hull: ";
        for (const Point3D& p : hull) {
            cout << "(" << p.x << ", " << p.y << ", " << p.z << ") ";
        }
        cout << endl;
    }
    
    return 0;
}

但对于三维情况,就需要做一些额外的处理来确定各个面是由哪些点构成。一种常见的方法是通过计算点的顺序来确定面的方向,具体步骤如下:

对凸包点坐标序列做一个深拷贝,记为hull_copy。
按照右手法则,判断hull_copy中相邻三个点的顺序是否为逆时针(对于凸多面体,逆时针为内侧normal方向)。如果为顺时针,则将中间那个点与前一个点交换位置。
重复上一步,直到hull_copy中所有相邻三点的顺序都为逆时针。
最终hull_copy中,每相邻三点就构成了一个面。

下面是使用C++实现上述方法的代码:


cppCopy code#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

struct Point3D {
    double x, y, z;
    Point3D(double x, double y, double z) : x(x), y(y), z(z) {}
};

vector<vector<Point3D>> getFaces(const vector<Point3D>& hull) {
    vector<vector<Point3D>> faces;
    vector<Point3D> hull_copy = hull;

    // 确保点的顺序为逆时针
    for (int i = 0; i < hull_copy.size(); i++) {
        int j = (i + 1) % hull_copy.size();
        int k = (i + 2) % hull_copy.size();
        Point3D& p1 = hull_copy[i];
        Point3D& p2 = hull_copy[j];
        Point3D& p3 = hull_copy[k];

        double x1 = p2.x - p1.x, y1 = p2.y - p1.y, z1 = p2.z - p1.z;
        double x2 = p3.x - p1.x, y2 = p3.y - p1.y, z2 = p3.z - p1.z;
        double cross_x = y1 * z2 - z1 * y2;
        double cross_y = z1 * x2 - x1 * z2;
        double cross_z = x1 * y2 - y1 * x2;

        if (cross_x < 0 || (cross_x == 0 && cross_y < 0) || (cross_x == 0 && cross_y == 0 && cross_z < 0)) {
            swap(hull_copy[j], hull_copy[k]);
        }
    }

    // 构造面
    for (int i = 0; i < hull_copy.size(); i++) {
        int j = (i + 1) % hull_copy.size();
        int k = (i + 2) % hull_copy.size();
        faces.push_back({hull_copy[i], hull_copy[j], hull_copy[k]});
    }

    return faces;
}

int main() {
    // 假设无人机坐标存储在drones_list中
    vector<Point3D> drones = {
        Point3D(0, 3, 1), Point3D(1, 1, 2), Point3D(2, 2, 3), Point3D(4, 4, 4),
        Point3D(0, 0, 0), Point3D(1, 2, 1), Point3D(3, 1, 2), Point3D(3, 3, 3)
    };

    vector<Point3D> hull = grahamScan(drones); // 获取凸包点
    vector<vector<Point3D>> faces = getFaces(hull); // 获取构成面的点

    // 输出结果
    cout << "Convex Hull Faces:" << endl;
    for (const auto& face : faces) {
        cout << "Face: ";
        for (const Point3D& p : face) {
            cout << "(" << p.x << ", " << p.y << ", " << p.z << ") ";
        }
        cout << endl;
    }

    return 0;
}

在上述代码中,getFaces函数实现了确定每个面的点序列的逻辑。它首先对hull做一个拷贝,然后遍历这个拷贝,对每三个相邻点,根据叉积判断它们的顺序是否为逆时针,如果不是则交换中间两点的位置。最终hull_copy中每三个相邻点就构成了一个面。
在main函数中,我们首先获取无人机坐标的凸包hull,然后调用getFaces(hull)获取每个面的点序列,最后输出结果。

效果不好,算法有问题

通过射线扫中的范围来确定

标签:p2,p1,效果,hull,double,雷达,copy,Point3D
From: https://www.cnblogs.com/aultcarius/p/18176026

相关文章

  • NGUI还原梦幻西游字体效果
    最终效果步骤进入梦幻西游所在文件夹,打开font目录,拷贝华康圆体hkyt.ttf到Unity工程目录。打开FontMaker,生成对应字体asset。此时的效果如下可以看到,效果还不错,但是看着有点累。用腾讯QQ的截图软件可以对比细节。可以发现网易的字体普遍有明亮的结构。所以肯定调高了亮度。......
  • 网页布局------轮播图效果实现
    纯css实现轮播图可以看这里:纯css实现轮播图(自动轮播和手动轮播)效果_☆*往事随風*☆的博客_css轮播图-CSDN博客代码来源:html+css+jquery实现轮播图自动切换、左右切换、点击切换_jquery图片轮播幻灯片效果实现左右滚动图片切换代码-CSDN博客JS实现轮播图的三种简单方法。_js轮播......
  • HPA* (Near Optimal hierarchical Path-finding)算法的效果图
    本文中的图全部来自:https://mohitsharma0690.blogspot.com/2016/01/hierarchical-pathfinding.html图的说明:Hereisanexampleofhowclustersarecreatedinanopenspaceenvironment.Thewhitesquaresrepresentwalkablegrids.Non-walkablegridspacesaremark......
  • Unity2D横版游戏之平台跳跃效果
    Unity2D横版游戏之平台跳跃效果简单介绍平台跳跃效果。玩家允许在平台下方跳跃到平台上方,并且可以在平台上方站立,同时玩家在平台上方允许通过下跳操作到达平台下方。实现步骤(一)将玩家的图片设置为Player、将平台的图层设置为Platform。(二)为平台游戏对象创建XXXCollider2D......
  • Unity2D横板游戏之背景视差与无限滚动效果
    Unity2D横板游戏之背景视差与无限滚动效果简单介绍背景视差效果。在2D横板游戏中,由若干个背景图片构成的背景,在背景移动的过程中,每一个背景图片的移动速度均不同,靠近玩家的背景图片移动速度快,而远离玩家的背景图片移动速度慢,从而形成背景的视差效果,使背景更加立体且富有层级。......
  • threejs - js库 gui 的使用 调试开发3D效果
    //导入threejsimport*asTHREEfrom"three";import{OrbitControls}from"three/examples/jsm/controls/OrbitControls.js";//引入dat.gui.js的一个类GUIimport{GUI}from'three/addons/libs/lil-gui.module.min.js';//创建场景scene......
  • C#托盘图标动画效果 - 开源研究系列文章
          这次在编写一个CPU使用率的小应用,上次发布了获取CPU使用率的代码,这次研究的是托盘图标的动画效果的问题。      托盘图标的动画效果,其实是多个图标,然后在时间内进行切换显示,形成的动画效果。这里笔者推荐两种方法:1、Timer计时器方法;就是设置一个T......
  • 目标错位是导致效果不佳的最终原因
    很多事情没有做好其实是目标定位错了,就如上课听讲,目标应该是消化理解老师输出的知识,而有时我们却会过分看重做笔记,把目标不知不觉中变成了做好笔记,其实当做笔记影响理解知识的时候应该果断的抛弃笔记。还有目前的小孩保护法,其最主要的目标应该是预防犯罪,最终却将主要目标变成了保......
  • vue路由切换滑动效果 vue页面跳转交互 vue实现动画跳转
    Hello,大家好,我是小编鹏仔,鹏仔一直觉得VUE在H5端路由跳转时交互特别丑,一直想写成那种点击滑动切换类的效果,趁着这两天工作不是很忙就网上搜了下,最终在多个搜索结果中选择了一种方式实现,效果如下图所示,点击路由跳转时是页面是滑动切换。逻辑其实还是很简单的,就是监听在路由切换时加......
  • ShellExperienceHost.exe 是 Windows 10 操作系统中的一个系统进程,它负责管理和运行一
    ShellExperienceHost.exe是Windows10操作系统中的一个系统进程,它负责管理和运行一些用户界面相关的功能和效果。具体来说,ShellExperienceHost主要有以下作用:启动菜单和任务栏:ShellExperienceHost负责启动、管理和渲染开始菜单、任务栏以及相关的用户界面元素。窗......