Advertisement
BorrowTheProgrammer

MainGraph_cpp

Jun 12th, 2022
1,086
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.67 KB | None | 0 0
  1. // Fill out your copyright notice in the Description page of Project Settings.
  2.  
  3.  
  4. #include "MainGraph.h"
  5.  
  6. #include "FloatingActor.h"
  7. #include "Components/LineBatchComponent.h"
  8. #include "Components/StaticMeshComponent.h"
  9. #define MAX_LABEL 100000
  10.  
  11. // Sets default values
  12. AMainGraph::AMainGraph()
  13. {
  14.     // Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
  15.     PrimaryActorTick.bCanEverTick = true;
  16.     LineBatch = CreateDefaultSubobject<ULineBatchComponent>(TEXT("LineBatch"));
  17.     LineBatch->SetupAttachment(RootComponent);
  18.     LineBatch->SetRelativeLocation(FVector(0.0f));
  19.     ActorSpeed = 100.0f;
  20.    
  21. }
  22.  
  23. // Called when the game starts or when spawned
  24. void AMainGraph::BeginPlay()
  25. {
  26.     Super::BeginPlay();
  27.     NewConjectureMatrix();
  28.     InitializeConjectureMatrix();
  29.     FillConjectureMatrix();
  30.     //AddStaticMeshes();
  31.    
  32.     for(int i = 0; i < Ribs.size(); ++i)
  33.     {
  34.         LineBatch->DrawPoint(Points[Ribs[i][0]], FLinearColor(1, 0, 1), 20, 1);
  35.         LineBatch->DrawPoint(Points[Ribs[i][1]], FLinearColor(1, 0, 1), 20, 1);
  36.         LineBatch->DrawLine(Points[Ribs[i][0]], Points[Ribs[i][1]], FLinearColor(0, 1, 0),
  37.             0, 4);
  38.     }
  39.     CreateActorsToMove();
  40. }
  41.  
  42. // Called every frame
  43. void AMainGraph::Tick(float DeltaTime)
  44. {
  45.     Super::Tick(DeltaTime);
  46.  
  47. }
  48.  
  49. void AMainGraph::OnConstruction(const FTransform& Transform)
  50. {
  51.     Super::OnConstruction(Transform);
  52.    
  53.     NewConjectureMatrix();
  54.     InitializeConjectureMatrix();
  55.     FillConjectureMatrix();
  56.    
  57.     LineBatch->Flush();
  58.    
  59.     for(int i = 0; i < Ribs.size(); ++i)
  60.     {
  61.         LineBatch->DrawPoint(Points[Ribs[i][0]], FLinearColor(1, 0, 1), 20, 1);
  62.         LineBatch->DrawPoint(Points[Ribs[i][1]], FLinearColor(1, 0, 1), 20, 1);
  63.         LineBatch->DrawLine(Points[Ribs[i][0]], Points[Ribs[i][1]], FLinearColor(0, 1, 0),
  64.             0, 4);
  65.     }
  66.    
  67. }
  68.  
  69. double AMainGraph::Random(const double Min, const double Max)
  70. {
  71.     return (double)(rand()) / RAND_MAX * (Max - Min) + Min;
  72. }
  73.  
  74. void AMainGraph::NewConjectureMatrix()
  75. {
  76.     for(int i = 0; i < GraphPointsCountX; ++i)
  77.     {
  78.         for(int j = 0; j < GraphPointsCountY; ++j)
  79.         {
  80.             float RandX = Random(0, OffsetX) * 1;
  81.             float RandY = Random(0, OffsetY) * 1;
  82.             float RandZ = Random(0, OffsetZ) * 1;
  83.             this->Points.push_back(FVector(RandX + 300.0f * i, RandY + 300.0f * j, RandZ + OffsetZ));
  84.         }
  85.     }
  86.  
  87.     for(int i = 0; i < GraphPointsCountX - 1; ++i)
  88.     {
  89.         for(int j = 0; j < GraphPointsCountY - 1; ++j)
  90.         {
  91.             std::vector<int> Temp;
  92.             Temp.push_back(GraphPointsCountY * i + j);
  93.             Temp.push_back(GraphPointsCountY * i + j + 1);
  94.            
  95.             if(rand() % 15 != 0)
  96.             {
  97.                 this->Ribs.push_back(Temp);
  98.             }
  99.            
  100.             Temp.clear();
  101.  
  102.             Temp.push_back(GraphPointsCountY * (GraphPointsCountX - 1) + j);
  103.             Temp.push_back(GraphPointsCountY * (GraphPointsCountX - 1) + j + 1);
  104.             if(rand() % 10 != 0)
  105.             {
  106.                 this->Ribs.push_back(Temp);
  107.             }
  108.  
  109.             Temp.clear();
  110.             Temp.push_back(GraphPointsCountY * i + j);
  111.             Temp.push_back(GraphPointsCountY * i + j + GraphPointsCountY);
  112.             if(rand() % 5 != 0)
  113.             {
  114.                 this->Ribs.push_back(Temp);
  115.             }
  116.  
  117.             Temp.clear();
  118.             Temp.push_back(GraphPointsCountY * i + j);
  119.             Temp.push_back(GraphPointsCountY * i + j + GraphPointsCountY + 1);
  120.             this->Ribs.push_back(Temp);
  121.         }
  122.     }
  123. }
  124.  
  125. void AMainGraph::InitializeConjectureMatrix()
  126. {
  127.     std::vector<double> Row;
  128.     for(int i = 0; i < (int)Points.size(); ++i)
  129.     {
  130.         Row.clear();
  131.         for(int j = 0; j < (int)Points.size(); ++j)
  132.         {
  133.             Row.push_back(0.0);
  134.         }
  135.         Matrix.push_back(Row);
  136.     }
  137. }
  138.  
  139. void AMainGraph::FillConjectureMatrix()
  140. {
  141.     for(int i = 0; i < (int)Ribs.size(); ++i)
  142.     {
  143.         double X1, X2, Y1, Y2, Z1, Z2;
  144.         int Point1 = Ribs[i][0];
  145.         int Point2 = Ribs[i][1];
  146.         X1 = Points[Point1].X;
  147.         Y1 = Points[Point1].Y;
  148.         Z1 = Points[Point1].Z;
  149.  
  150.         X2 = Points[Point2].X;
  151.         Y2 = Points[Point2].Y;
  152.         Z2 = Points[Point2].Z;
  153.  
  154.         double RibLength = sqrt(pow((X1 - X2), 2) + pow((Y1 - Y2), 2) + pow((Z1 - Z2), 2));
  155.         Matrix[Point2][Point1] = RibLength;
  156.         Matrix[Point1][Point2] = RibLength;
  157.     }
  158. }
  159.  
  160. std::vector<int> AMainGraph::GetShortPath(int start, int end)
  161. {
  162.     int N = Matrix.size();
  163.  
  164.     std::vector<float> vertex_labels;
  165.     std::vector<bool> vertex_visited;
  166.     std::vector<int> found_path;
  167.     for (int i = 0; i < N; ++i) {
  168.         vertex_labels.push_back(MAX_LABEL);
  169.         vertex_visited.push_back(false);
  170.         found_path.push_back(start);
  171.     }
  172.  
  173.     vertex_labels[start] = 0;
  174.  
  175.     int current_vertex = start;
  176.     do {
  177.         // поиск соседа-вершины с минимальным расстоянием
  178.         for (int i = 0; i < N; ++i) {
  179.             // расстояние от текущей вершины до вершины i
  180.             float h = (Matrix[current_vertex])[i];
  181.             // если расстояние = 0, то пути нет
  182.             if (h == 0) continue;
  183.             // если расстояние не 0, то проверка на текущую метку вершины5
  184.             if (h + vertex_labels[current_vertex] < vertex_labels[i]) {
  185.                 vertex_labels[i] = h + vertex_labels[current_vertex];
  186.                 found_path[i] = current_vertex;
  187.             }
  188.         }
  189.         vertex_visited[current_vertex] = true;  // отмечаем вершину как посещенную
  190.  
  191.         // ищем соседа с минимальным расстоянием и заменяем индекс
  192.         float minimal_pathsum;
  193.         float min_index = vertex_labels.size() + 1;
  194.  
  195.         for (int i = 0; i < (int)vertex_labels.size(); ++i) {
  196.             if ((!vertex_visited[i]) && (vertex_labels[i] < MAX_LABEL)) {
  197.                 minimal_pathsum = vertex_labels[i];
  198.                 min_index = i;
  199.             }
  200.         }
  201.         current_vertex = min_index;
  202.     } while (current_vertex != vertex_labels.size() + 1);
  203.  
  204.     // кратчайший путь
  205.     std::vector<int> shortPath;
  206.     // индексация от конца к началу
  207.     int index = end;
  208.     while (index != start) {
  209.         shortPath.push_back(index);
  210.         index = found_path[index];
  211.     }
  212.     shortPath.push_back(start);
  213.  
  214.     return shortPath;
  215.    
  216. }
  217.  
  218. void AMainGraph::CreateActorsToMove()
  219. {
  220.     int RandomPointStartIndex, RandomPointEndIndex;
  221.     FVector Point;
  222.     AFloatingActor *ActorToMove;
  223.    
  224.     for(int i = 0; i < BallCount; ++i)
  225.     {
  226.         RandomPointStartIndex = FMath::RandRange(0, Points.size() - 1);
  227.  
  228.         do
  229.         {
  230.             RandomPointEndIndex = FMath::RandRange(0, Points.size() - 1);
  231.         } while (RandomPointEndIndex == RandomPointStartIndex);
  232.        
  233.         Point = Points[RandomPointStartIndex];
  234.        
  235.         FActorSpawnParameters Params;
  236.         Params.Owner = this;
  237.        
  238.         ActorToMove = GetWorld()->SpawnActor<AFloatingActor>(Params);
  239.         ActorToMove->AttachToComponent(LineBatch, FAttachmentTransformRules::KeepRelativeTransform);
  240.         ActorToMove->SetActorLocation(Point);
  241.         ActorToMove->SetStartPoint(RandomPointStartIndex);
  242.         ActorToMove->SetActorSpeed(ActorSpeed);
  243.         ActorToMove->SetPoints(Points);
  244.         ActorToMove->SetNumberOfActors(BallCount);
  245.         ActorToMove->CopyMatrix(Matrix);
  246.         ActorToMove->SetActorPathColor(GenerateActorColor());
  247.         Point = Points[RandomPointEndIndex];
  248.         ActorToMove->SetEndPoint(RandomPointEndIndex);
  249.         ActorToMove->SetActorShortPath(GetShortPath(RandomPointStartIndex, RandomPointEndIndex));
  250.         this->FloatingActors.push_back(ActorToMove);
  251.     }
  252. }
  253.  
  254. void AMainGraph::AddStaticMeshes()
  255. {
  256.     for(int i = 0; i < Points.size(); ++i)
  257.     {
  258.         //FName Name = *FString::Printf(TEXT("Cube %i"), i);
  259.         UStaticMeshComponent *MeshComponent = NewObject<UStaticMeshComponent>(this, UStaticMeshComponent::StaticClass());
  260.         MeshComponent->SetStaticMesh(Mesh);
  261.         MeshComponent->AttachToComponent(LineBatch, FAttachmentTransformRules::KeepRelativeTransform);
  262.         MeshComponent->RegisterComponentWithWorld(GetWorld());
  263.         MeshComponent->SetRelativeLocation(Points[i]);
  264.     }
  265. }
  266.  
  267. FLinearColor AMainGraph::GenerateActorColor()
  268. {
  269.     FLinearColor Color = FLinearColor(FMath::RandRange(0, 255), FMath::RandRange(0, 255),
  270.         FMath::RandRange(0, 255));
  271.     return Color;
  272. }
  273.  
  274.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement