当前位置: 首页 > wzjs >正文

网站优化设计公司软件开发定制价格表

网站优化设计公司,软件开发定制价格表,肇庆市网站建设,怎么查询域名目录 原理 效果 步骤 源码 原理 先设置绘制线段的起点和终点,然后我们将起点和终点的高度升高,然后通过插值,在起点和终点之间添加多个点,再由这些点向地心发出射线,这样我们就可以获取到这些点在地表的投影点&…

目录

原理

效果

步骤

源码


原理

        先设置绘制线段的起点和终点,然后我们将起点和终点的高度升高,然后通过插值,在起点和终点之间添加多个点,再由这些点向地心发出射线,这样我们就可以获取到这些点在地表的投影点,最后将投影点连起来就是地表贴合线。

        注意:使用该方法时,需要保证地形加载完毕,因为只要地形加载后地表才会有碰撞信息,才能被射线检测到

效果

步骤

1. 在“xxx.Build.cs”中引入“CesiumRuntime”模块

 2. 新建一个Actor类,这里命名为“SurfaceLineActor”

在“SurfaceLineActor.h”中添加所需头文件

定义一个函数“CalculatePointsOnSurface”用于计算地表点,该函数需要传入起点终点的经纬度、细分点数、起终点向上偏移的距离

再定义一个函数用于绘制地表贴合线,该函数需要传入地表点数组、线的颜色、线的粗细共3个参数。

定义地心坐标、添加一个LineBatchComponent组件用于高效绘制线条、定义一个数组“Points”用于储存起终点之间的点

实现函数“CalculatePointsOnSurface”如下

TArray<FVector> ASurfaceLineActor::CalculatePointsOnSurface(FVector StartPointLLA, FVector EndPointLLA, int32 NumberOfSegments, double TraceUpOffset)
{//将起点和终点拔高一段距离以方便往地心打射线StartPointLLA = StartPointLLA + FVector(0, 0, TraceUpOffset);EndPointLLA = EndPointLLA + FVector(0, 0, TraceUpOffset);//获取GeoreferenceACesiumGeoreference* Georeference = ACesiumGeoreference::GetDefaultGeoreference(GetWorld());if (!Georeference){UE_LOG(LogTemp, Warning, TEXT("SurfaceLineActor: CesiumGeoreference not found. Cannot calculate surface points."));}//将起终点(经纬高)转换为起终点(UE世界坐标)FVector StartPoint = Georeference->TransformLongitudeLatitudeHeightPositionToUnreal(StartPointLLA);FVector EndPoint = Georeference->TransformLongitudeLatitudeHeightPositionToUnreal(EndPointLLA);Points.Empty();if (NumberOfSegments <= 0)  // 分段数不满足要求,返回起点和终点{// 如果段数无效,至少包含起点和终点Points.Add(StartPoint);if (StartPoint != EndPoint) // 避免重复添加同一点{Points.Add(EndPoint);}}else{//Points.Reserve(NumberOfSegments + 1); // 预分配空间提高效率for (int32 i = 0; i < NumberOfSegments; ++i){float T = static_cast<float>(i) / static_cast<float>(NumberOfSegments);FVector CurrentPoint = FMath::Lerp(StartPoint, EndPoint, T);  // 使用 FMath::Lerp 进行线性插值计算点的坐标Points.Add(CurrentPoint);}}// 用于存储射线检测到的地表点TArray<FVector> CalculatedSurfacePoints;//起点和终点构成的连线中每个点都朝地心发出射线for (int32 i = 0; i < Points.Num(); ++i){FHitResult HitResult;FCollisionQueryParams QueryParams;QueryParams.AddIgnoredActor(this);        // 射线检测忽视自身//QueryParams.AddIgnoredActors(ActorsToIgnore); // 忽视射线检测的ActorQueryParams.bTraceComplex = true;         // 使用复杂碰撞QueryParams.bReturnPhysicalMaterial = false; // 是否检测物理材料ECollisionChannel TraceChannel = ECC_Visibility;UWorld* World = GetWorld();bool bHit = World->LineTraceSingleByChannel(HitResult,      // 射线检测结果Points[i],      // 射线起点EarthOrigin,    // 射线终点(地心)TraceChannel,   // 射线碰撞通道QueryParams     // 射线碰撞其他参数);画射线检测(非必需)//DrawDebugLine(//    GetWorld(),//    Points[i],    //起点//    EarthOrigin,  //终点(地心)//    bHit ? FColor::Green : FColor::Red,  //颜色//    false,           // false表示它持续“LifeTime”,如果LifeTime为0,则持续一帧//    0.0,             // DebugLine生命周期时长//    0,               // DepthPriority (0 for SDPG_World)//    2.0f//);if (bHit){画射线碰撞点(非必需)//DrawDebugSphere(//    GetWorld(),//    HitResult.Location,//    30.0f, // Radius//    12,                // Segments//    FColor::Cyan,//    false,             // Persistent lines//    0.0f   // Lifetime//);FVector OutHitLocation = HitResult.ImpactPoint;CalculatedSurfacePoints.Add(OutHitLocation);}}return CalculatedSurfacePoints;
}

3. 测试一下“CalculatePointsOnSurface”函数是否生效,这里设置起点为成都市市中心终点为都江堰

运行后可以看到地表点位置基本准确

4. 接下来只需要通过LineBatchComponent组件将地表点连线即可

函数“DrawSurfaceLine”实现如下

void ASurfaceLineActor::DrawSurfaceLine(TArray<FVector> SurfacePoints, FLinearColor LineColor, float LineThickness)
{if (!LineBatchComponent){UE_LOG(LogTemp, Warning, TEXT("SurfaceLineActor: LineBatchComponent is null."));return;}LineBatchComponent->Flush(); // 清除之前的线if (SurfacePoints.Num() >= 2){for (int32 i = 0; i < SurfacePoints.Num() - 1; ++i){if (SurfacePoints[i].ContainsNaN() || SurfacePoints[i + 1].ContainsNaN()){UE_LOG(LogTemp, Warning, TEXT("SurfaceLineActor: Encountered NaN point at segment %d, skipping draw."), i);continue;}LineBatchComponent->DrawLine(SurfacePoints[i],SurfacePoints[i + 1],LineColor,SDPG_World, // 场景深度优先级组-根据渲染顺序需要进行调整LineThickness,0.0f        // 线的生命周期时长:0表示无限生命);}}
}

再通过蓝图在获取地表点数组后传入函数 “DrawSurfaceLine”

此时效果如下: 

 5. 选取山地进行测试,插值数量设置为200,此时运行效果如下

源码

 “SurfaceLineActor.h”

// Fill out your copyright notice in the Description page of Project Settings.#pragma once#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Components/LineBatchComponent.h"
#include "CesiumGeoreference.h"
#include "SurfaceLineActor.generated.h"UCLASS()
class GLOBEPAWNTEST_API ASurfaceLineActor : public AActor
{GENERATED_BODY()public:	// Sets default values for this actor's propertiesASurfaceLineActor();// 计算地表点UFUNCTION(BlueprintCallable, Category = "Line Properties")TArray<FVector> CalculatePointsOnSurface(FVector StartPointLLA = FVector(0, 0, 0),FVector EndPointLLA = FVector(0, 0, 0),int32 NumberOfSegments = 50,     // 线段细分数 (越高质量越好,但性能开销越大)double TraceUpOffset = 100000.0  // 射线检测时向上偏移的距离(确保起点在潜在地形之上)  默认100km);// 调用此函数来绘制或更新地表贴合线UFUNCTION(BlueprintCallable, Category = "Line Properties")void DrawSurfaceLine(TArray<FVector> SurfacePoints,FLinearColor LineColor = FLinearColor::Red, // 线的颜色float LineThickness = 10.0f    // 线的粗细);//地心坐标UPROPERTY(EditAnywhere, BlueprintReadWrite)FVector EarthOrigin = FVector(0, 0, -637810000.0);protected:// Called when the game starts or when spawnedvirtual void BeginPlay() override;UPROPERTY(VisibleAnywhere, BlueprintReadOnly)ULineBatchComponent* LineBatchComponent;public:	// Called every framevirtual void Tick(float DeltaTime) override;private:TArray<FVector> Points;  //用于存储起点和终点连线之间的点
};

 “SurfaceLineActor.cpp”

// Fill out your copyright notice in the Description page of Project Settings.#include "SurfaceLineActor.h"
#include "CesiumRuntime/Public/CesiumGeoreference.h"// Sets default values
ASurfaceLineActor::ASurfaceLineActor()
{// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.PrimaryActorTick.bCanEverTick = true;PrimaryActorTick.bStartWithTickEnabled = true;LineBatchComponent = CreateDefaultSubobject<ULineBatchComponent>(TEXT("LineBatcher"));// 可以将 LineBatchComponent 设为根组件,或者附加到其他组件上RootComponent = LineBatchComponent;LineBatchComponent->bCalculateAccurateBounds = false; // Optimization for dynamic lines}// Called when the game starts or when spawned
void ASurfaceLineActor::BeginPlay()
{Super::BeginPlay();}// Called every frame
void ASurfaceLineActor::Tick(float DeltaTime)
{Super::Tick(DeltaTime);}void ASurfaceLineActor::DrawSurfaceLine(TArray<FVector> SurfacePoints, FLinearColor LineColor, float LineThickness)
{if (!LineBatchComponent){UE_LOG(LogTemp, Warning, TEXT("SurfaceLineActor: LineBatchComponent is null."));return;}LineBatchComponent->Flush(); // 清除之前的线if (SurfacePoints.Num() >= 2){for (int32 i = 0; i < SurfacePoints.Num() - 1; ++i){if (SurfacePoints[i].ContainsNaN() || SurfacePoints[i + 1].ContainsNaN()){UE_LOG(LogTemp, Warning, TEXT("SurfaceLineActor: Encountered NaN point at segment %d, skipping draw."), i);continue;}LineBatchComponent->DrawLine(SurfacePoints[i],SurfacePoints[i + 1],LineColor,SDPG_World, // 场景深度优先级组-根据渲染顺序需要进行调整LineThickness,0.0f        // 线的生命周期时长:0表示无限生命);}}
}TArray<FVector> ASurfaceLineActor::CalculatePointsOnSurface(FVector StartPointLLA, FVector EndPointLLA, int32 NumberOfSegments, double TraceUpOffset)
{//将起点和终点拔高一段距离以方便往地心打射线StartPointLLA = StartPointLLA + FVector(0, 0, TraceUpOffset);EndPointLLA = EndPointLLA + FVector(0, 0, TraceUpOffset);//获取GeoreferenceACesiumGeoreference* Georeference = ACesiumGeoreference::GetDefaultGeoreference(GetWorld());if (!Georeference){UE_LOG(LogTemp, Warning, TEXT("SurfaceLineActor: CesiumGeoreference not found. Cannot calculate surface points."));}//将起终点(经纬高)转换为起终点(UE世界坐标)FVector StartPoint = Georeference->TransformLongitudeLatitudeHeightPositionToUnreal(StartPointLLA);FVector EndPoint = Georeference->TransformLongitudeLatitudeHeightPositionToUnreal(EndPointLLA);Points.Empty();if (NumberOfSegments <= 0)  // 分段数不满足要求,返回起点和终点{// 如果段数无效,至少包含起点和终点Points.Add(StartPoint);if (StartPoint != EndPoint) // 避免重复添加同一点{Points.Add(EndPoint);}}else{//Points.Reserve(NumberOfSegments + 1); // 预分配空间提高效率for (int32 i = 0; i < NumberOfSegments; ++i){float T = static_cast<float>(i) / static_cast<float>(NumberOfSegments);FVector CurrentPoint = FMath::Lerp(StartPoint, EndPoint, T);  // 使用 FMath::Lerp 进行线性插值计算点的坐标Points.Add(CurrentPoint);}Points.Add(EndPoint);  //需要加上终点}// 用于存储射线检测到的地表点TArray<FVector> CalculatedSurfacePoints;//起点和终点构成的连线中每个点都朝地心发出射线for (int32 i = 0; i < Points.Num(); ++i){FHitResult HitResult;FCollisionQueryParams QueryParams;QueryParams.AddIgnoredActor(this);        // 射线检测忽视自身//QueryParams.AddIgnoredActors(ActorsToIgnore); // 忽视射线检测的ActorQueryParams.bTraceComplex = true;         // 使用复杂碰撞QueryParams.bReturnPhysicalMaterial = false; // 是否检测物理材料ECollisionChannel TraceChannel = ECC_Visibility;UWorld* World = GetWorld();bool bHit = World->LineTraceSingleByChannel(HitResult,      // 射线检测结果Points[i],      // 射线起点EarthOrigin,    // 射线终点(地心)TraceChannel,   // 射线碰撞通道QueryParams     // 射线碰撞其他参数);画射线检测(非必需)//DrawDebugLine(//    GetWorld(),//    Points[i],    //起点//    EarthOrigin,  //终点(地心)//    bHit ? FColor::Green : FColor::Red,  //颜色//    false,           // false表示它持续“LifeTime”,如果LifeTime为0,则持续一帧//    0.0,             // DebugLine生命周期时长//    0,               // DepthPriority (0 for SDPG_World)//    2.0f//);if (bHit){画射线碰撞点(非必需)//DrawDebugSphere(//    GetWorld(),//    HitResult.Location,//    30.0f, // Radius//    12,                // Segments//    FColor::Cyan,//    false,             // Persistent lines//    0.0f   // Lifetime//);FVector OutHitLocation = HitResult.ImpactPoint;CalculatedSurfacePoints.Add(OutHitLocation);}}return CalculatedSurfacePoints;
}
http://www.dtcms.com/wzjs/541963.html

相关文章:

  • 网站运营与管理的一个目的网站建设交易中心
  • wordpress实现网站的登陆功能东庄水利建设公司网站
  • 企业网站一般做多宽网络工程专业毕业生设计
  • 安徽建设厅网站怎么打不开wordpress导航去掉多余的样式
  • 网站建设和运行遇到的问题贵阳网站设计公司
  • 毕业网站建设开题报告专业制作网站用哪些软件
  • 国外网站代理福州建设银行官网招聘网站
  • 苏州seo网站推广怎么做导航网站
  • 做网站有名的公司从网页上直接下载视频
  • 网站后台培训网站模板制作工具
  • 做百度网站好吗网页设计制作音乐排行榜
  • php做企业网站需要多久滨州改版网站建设服务
  • 定州市住房和城乡建设局 网站ui设计哪里培训机构
  • 昆山网站建设第一品牌洛阳市网站建设管理
  • 信息手机网站模板下载软件做网站领券收佣金
  • 做什么网站能吸引流量wordpress loginview
  • 比较顺口的公司名字关键词首页优化
  • 网站开发成本有哪些万网首页
  • 网站建设的规划书企业管理咨询与诊断实践报告
  • 泉州专业网站建设公司买外链
  • 鹤岗住房和城乡建设局网站网站建设算什么费用
  • 免费舆情信息网站珠海市研发网站建设
  • 值得相信的西安网站开发自学商城网站建设
  • 水滴保险官方网站php做的网站手机能看到
  • 帝国cms做笑话网站多个端口网站如何做域名重定向
  • 检察网站建设龙华网站建设-信科网络
  • 武都区建设局网站物流公司怎么做网站
  • 网站关键词优化案例辽宁省阜蒙县建设局网站
  • 金融类网站源码电商网站开发技术与维护
  • 怎么建自己的摄影网站weex做网站