RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / user-368826

artem_tmm's questions

Martin Hope
artem_tmm
Asked: 2024-02-17 19:10:43 +0000 UTC

圆柱体和长方体(在特定情况下为立方体)的交集

  • 5

该框由两个点 Bmax(X_max, Y_max, Z_max) 和 Bmin(X_min, Y_min, Z_min) 定义。从这两点你可以确定盒子的剩余6个顶点,例如:(X_max,Y_max,Z_min),(X_max,Y_min,Z_max)等等......

圆柱体由其底边的两个中心 O1(x1,y1,z1)、O2(x2,y2,z2) 和半径 R 定义。

那些。圆柱体可以处于不同的角度,不一定处于严格的垂直位置,并且立方体始终严格沿轴对齐。

我的任务是确定圆柱体是否与立方体相交。

首先我想实现以下算法:

  1. 判断是否至少有一端在盒子内部,则相交
  2. 如果两端都在盒子外面,那么对于立方体的每个面,求平面方程,并检查平面是否与圆柱体相交。但这仍然不是我们检查平面是否与圆柱体相交的方法,我'我不确定这是正确的验证算法。

然后我找到了一个描述另一种算法的文档: https ://www.geometrictools.com/Documentation/IntersectionBoxCylinder.pdf

及其源代码:https://www.geometrictools.com/Downloads/Downloads.html文件 - (GTEngine 7.0 Distribution (ZIP))

我开始测试算法,但结果与预期结果不符。

我是如何测试的:

  1. 解压存档
  2. 打开解决方案GeometricTools\GTE\Samples\Intersection\IntersectBoxCylinder\IntersectBoxCylinderDX11.v16.sln
  3. 我开始调试并渲染场景:

在此输入图像描述

了解 IntersectBoxCylinderWindow3.cpp 后,我意识到当一个盒子与圆柱体相交时,它会使用 TestIntersection() 方法变成红色。您还可以在 CreateScene() 方法中更改形状(长方体和圆柱体)的初始坐标和大小

我设置了拳击的参数:

    mCylinder.axis.origin = { 0.0f, 0.0f, 1.5f }; // основание цилиндра
    mCylinder.axis.direction = { 0.0f, 0.0f, 1.0f };// направление (можно вычислить если знаем координаты конца и начала)
    mCylinder.radius = 1.0f; // радиус
    mCylinder.height = 1.0f; // высота
    
    mBox.center = { 0.5f, 0.5f, 0.5f }; // центр 
    mBox.axis[0] = { 1.0f, 0.0f, 0.0f }; // угол поворота бокса (в моем случае никогда не изменяется)
    mBox.axis[1] = { 0.0f, 1.0f, 0.0f }; 
    mBox.axis[2] = { 0.0f, 0.0f, 1.0f };
    mBox.extent = { 0.5f, 0.5f, 0.5f }; // Эксцент

我们调试发现没有交集,但算法修复了它并使框变为红色

在此输入图像描述

  1. 我通过编写以下代码检查了同样的事情:
#include <iostream>
#include "Mathematics/IntrAlignedBox3Cylinder3.h"
#include "Mathematics/Cylinder3.h"
#include "Mathematics/Vector3.h"
#include "Mathematics/Vector.h"
#include "Mathematics/AlignedBox.h"
#include <cmath>
#include <limits.h>
#include <float.h>

// расстояние между точками в пространстве 
static double PointPointDistance(Vector3<double> const& point1, Vector3<double> const& point2)
{
    return sqrt(pow(point1[0] - point2[0], 2) + pow(point1[1] - point2[1], 2) + pow(point1[2] - point2[2], 2));
}

int32_t main()
{
    // центры оснований
    Vector3<double> start = {0,0,1.5};
    Vector3<double> end = {0,0,2.5};
    // высота цилиндра
    double height = PointPointDistance(start, end);
    // направление цилиндра
    Vector3<double> dir = end - start;
    Normalize(dir);
    Cylinder3<double> cylinder;
    cylinder.axis.direction = dir;
    cylinder.axis.origin = start;
    cylinder.radius = 1;
    cylinder.height = height;
   
    AlignedBox3<double> box;
    // минимальная/максимальная вершина
    box.min = { 0,0,0 };
    box.max = { 1,1,1 };

    // хит тест
    TIQuery<double, AlignedBox3<double>, Cylinder3<double>> mQuery;
    bool result = mQuery(box,cylinder).intersect;

    return 0;
}

结果也是如此,虽然事实上并非如此

此外,其他几个测试也失败了

我没有找到任何其他具有实现的库,因此我无法自己实现该算法。

有知道的分享一下方法

геометрия
  • 1 个回答
  • 32 Views
Martin Hope
artem_tmm
Asked: 2024-02-05 18:11:07 +0000 UTC

在空间中旋转线段

  • 6

输入是空间中的一些随机线段,其两端的坐标为 p1(x1,y1,z1) 和 p2(x2,y2,z2)。

任务如下 - 有必要对其坐标进行此类转换,使其严格垂直,同时保持其长度。图片中的演示(绿色 - 原始,蓝色 - 旋转)。

在此输入图像描述

  1. 这个想法是取原始线段上的任意点(用 A1 表示),并添加第二个点 (A2),该点比点 A1 高出原始线段的长度。但这是行不通的,因为我们应用于该段以旋转它的变换将应用于其他 3D 对象。

  2. 还有一个想法是计算线段与所有轴(x、y、z)之间的角度,然后将线段的所有坐标依次乘以沿所有轴的旋转矩阵。但执行此操作后的新段并没有达到预期(看起来不直)。

这里我将坐标依次乘以这3个矩阵在此输入图像描述

预先知道角度 alpha、beta、gamma 为 45 度,可以检查角度是否取正确,图中(绿色部分),例如坐标为 p1(0,0,0) p2(1 ,1,1) 被取

尝试实现获取旋转矩阵的算法:

import numpy as np

# нормализовать вектор (привести к единичной длине)
def normalize_vector(vector):
    norm_v = np.linalg.norm(vector)
    if norm_v != 0:
        return vector / norm_v
    else:
        return vector

# Исходные данные задачи (2 конца отрезка)
x = np.array([0,0,0])
y = np.array([1,1,1])

#нормализуем вектора
x = normalize_vector(x)
y = normalize_vector(y)

# необходимые вектора для решения задачи
s = np.array([y[0] - x[0],y[1] - x[1],y[2] - x[2]])
t = np.array([0,1,0])
a = np.cross(s,t)

#нормализуем вектора
s = normalize_vector(s)
t = normalize_vector(t)
a = normalize_vector(a)

# матрицы
S = np.array([s, a, np.cross(s,a)])
T = np.array([t, a, np.cross(t,a)])

#транспонированная S
S_t = np.transpose(S)

# получаем решение задачи
solution = np.dot(S_t, T)

# тестируем, пробуем получить повернутый отрезок
x = np.array([[0,0,0]])
y = np.array([[1,1,1]])
x = np.dot(x, solution)
y = np.dot(y, solution)
x = np.round(x, decimals=2)
y = np.round(y, decimals=2)

print(x, y)
геометрия
  • 2 个回答
  • 91 Views
Martin Hope
artem_tmm
Asked: 2022-07-10 22:49:29 +0000 UTC

将文件下载到内存流c#

  • 0

如何将文件从 Yandex 磁盘下载到内存流。我很久没能找到这方面的信息了。

尝试过这样的事情

            string token = "AQAAAABb39FLAAeXvhANBxjOrEkOrH8U7giSBSs";
            var api = new DiskHttpApi(token);

            using (MemoryStream ms = new MemoryStream())
            {
                var link = await api.Files.GetDownloadLinkAsync("/" + folderName + "/" + "data.dat");

             }
c# передача-данных
  • 1 个回答
  • 41 Views
Martin Hope
artem_tmm
Asked: 2022-06-28 20:42:40 +0000 UTC

xml序列化

  • 0

如何序列化一个对象但不保存它,而是立即通过网络发送它,就像一个 xml 文件?

        private async void xmlSerialized(Object obj, string path)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(Object));

            using (FileStream fs = new FileStream(path, FileMode.OpenOrCreate))
            {
                // сохраняет файл в Debug а нужно отправить
                serializer.Serialize(fs, obj);
            }
           
          // тут функции для работы с Яндекс диском
 
           // ссылка
           var link = await api.Files.GetUploadLinkAsync("/" + folderName + "/" + xmlFile, overwrite: true);
           
           // в втором аргументе функция принимает сам файл типа fileStream
           await api.Files.UploadAsync(link, fs);
        }
c#
  • 1 个回答
  • 10 Views
Martin Hope
artem_tmm
Asked: 2022-05-16 19:30:15 +0000 UTC

fread 不从文件中读取数据

  • 0

有一个函数可以创建一个带有数字的二进制文件并从中读取。此外,还有一个函数,用于从可变数量的二进制文件中读取数字,将它们合并为一个,并返回一个指向包含该文件名称的字符串的指针。(Load_data) 问题是从二进制文件读取的函数拒绝从Load_data 函数返回的名称的文件中读取数据。

#define _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <windows.h>
#include <stdarg.h>
#include <conio.h>
#include "functions.h"
#include "vnsort_bin_dec.h"
#include "vnsort_bin_inc.h"
#include <string.h>
#include <stdio.h>

#define N 20

using namespace std;

char* Load_data(const char* path, ...)
{
    int i = 0, t;
    char *str = new char[N];

    FILE* f, *a;

    va_list path_ptr; //Объявление списка переменных аргументов

    const char* path_tmp = path; // инициализация указателя
    va_start(path_ptr, path); // инициализация списка переменных аргументов

    // создание файла
    puts("Введите имя файла!");
    gets_s(str, N);


    if ((a = fopen((char*)str, "wb")) == NULL)
    {
        printf("\n Файл %s не открывается", a);
        system("pause");
        //return;
    }
    else
    {
        do
        {
            f = fopen(path_tmp, "rb");
            fseek(f, 0L, 0);

            while (fread(&t, sizeof(int), 1, f))
            {
                // записываем все числа в один файл
                fwrite(&t, sizeof(int), 1, a);
                if (feof(f)) break;
                i++;
            }

            path_tmp = va_arg(path_ptr, const char*);

        } while (path_tmp);
    }

    puts("Данные загружены!");

    return str;
}

int creat_bin(char *a) // создание файла данных, ввод чисел с клавиатуры
{
    FILE* A;
    int n;

    if ((A = fopen(a, "wb")) == NULL)
    {
        printf("\n Файл %s не открывается", a);
        system("pause");
        return -1;
    }
    else
    {
        printf("\n Введите %d целых чисел: ", 5);
        for (size_t i = 0; i < 5; i++)
        {
            scanf_s("%d", &n);
            fwrite(&n, sizeof(int), 1, A);
        }
        fclose(A);
    }
}

int read_bin(char* a) // чтение файла данных
{
    FILE* A;
    int n;

    if ((A = fopen(a, "rb")) == NULL)
    {
        printf("\n Файл %s не открывается", a);
        system("pause");
        return -1;
    }
    else
    {
        //fseek(A, 0L, 0);
        while (fread(&n, sizeof(int), 1, A))
            cout << n << " "; 
        fclose(A);
    }
}

int main()
{
    SetConsoleCP(1251);
    SetConsoleOutputCP(1251);

    char *str;
    
    str = Load_data("t1", "t2", NULL);

    read_bin(str);

    return 0;
}
c++
  • 1 个回答
  • 10 Views
Martin Hope
artem_tmm
Asked: 2022-03-20 23:27:37 +0000 UTC

从单链表中删除元素

  • 0

任务:只保留列表中最后出现的相同元素。

struct List // Создание нового типа данных
{
    int value; // информационная часть
    List* next; // служебная часть
    List(int val = 0, List* p = NULL) // конструктор
    {
        value = val;
        next = p;
    }
};


List* head = NULL;


// Включение элемента в конец списка
List* Add_last(int n, List* head)
{
    List* q = new List(n), *p = head;
    if (head == NULL) return q;
    while (p->next != NULL)
        p = p->next;
    p->next = q;
    return head;
}


// Печать содержимого списка
void Print_list(List* head)
{
    List* p = head;
    puts("\n PRINT LIST");
    if (p == NULL) puts("Список пуст!");
    else
        while (p != NULL)
        {
            printf("%d ", p->value);
            p = p->next;
        }
}


List* remove(List * head) 
{
    List * j, *i = head , *t;
    int count = 0;

    while (i != NULL) // внешний цикл, обход списка
    { 
        for (j = i; j != NULL; j = j->next) // считаю количество одинаковых элементов
            if (j->value == i->value) count++; 

        j = i; // возвращаем указатель в начало


       while (count > 1)
        {
            if (i->value == j->value)
            {
                t = j;
                j = j->next;
                delete t;

                count--;
            }
            else j = j->next;
        }

        i = i->next;

        count = 0;
    }

    return head;
}


int main()
{
    SetConsoleCP(1251);
    SetConsoleOutputCP(1251);

    List* head = NULL;
 
    head = Add_last(1, head);
    head = Add_last(2, head);
    head = Add_last(1, head);
    head = Add_last(1, head);
    head = Add_last(4, head);

    Print_list(head);

    head = remove(head);

    printf("");

    Print_list(head);

    return 0;
}

程序在删除功能运行后停止运行

PS 列表是单链接的,所以我只能往一个方向移动。

c++
  • 1 个回答
  • 10 Views
Martin Hope
artem_tmm
Asked: 2022-02-05 14:07:41 +0000 UTC

从二叉搜索树中删除子树

  • 1

在任务中,我们有以下输入数据:

6

-2 0 2

8 4 3

9 0 0

3 6 5

600

0 0 0

四

6 9 7 8

其中第一个数字是二叉搜索树中的顶点数,随后的行存储有关顶点的数据。第一个数字是顶点键,第二个是左孩子描述的行号,第三个是右孩子描述的行号,如果没有左孩子或右孩子,那么在它们应该被描述为 0。下一个数字是删除请求的数量。接下来是键 - 需要删除的子树的根。

在输出中,您需要在执行每个删除具有给定键的子树的请求后打印树中剩余顶点的数量。具有给定键的子树可能不存在。

在这种情况下,输出将如下所示。

5 4 4 1

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <algorithm>
#include <conio.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>

using namespace std;


ifstream in("input.txt");
ofstream out("output.txt");


struct data
{
    int value, left, right;
    bool is_delete;
};


vector <data> data_tree;

int nodes = 0;

void input()
{
    int size_tree;

    in >> size_tree;

    if (size != 0)
    {

        for (int i = 0; i < size_tree; i++)
        {
            data add;
            in >> add.value >> add.left >> add.right;

            add.is_delete = false;

            data_tree.push_back(add);
        }
    }
}


void remove(int index, int key)
{
    // если узел считается удаленным то не можем двигаться дальше
    if (data_tree[index].is_delete == true)return;

    // если узел равен нашему ключу то говорим, что он удален и выходим
    if (data_tree[index].value == key)
    {
        data_tree[index].is_delete = true;
        return;
    }

    // двигаемся дальше по дереву
    if (data_tree[index].left != 0)remove(data_tree[index].left - 1, key);

    if (data_tree[index].right != 0)remove(data_tree[index].right - 1, key);
 
    // считаем количество пройденных узлов
    nodes++;
}



void delete_sub_tree()
{
    int size_tree, key;
    in >> size_tree;

    // ввод запросов и удаление поддеревьев
    for (int i = 0; i < size_tree; i++)
    {
        nodes = 0;

        in >> key;

        remove(0, key);
        
        out << nodes << endl;
    }
}



int main()
{

    input();         // ввод данных

    delete_sub_tree(); // удаление поддеревьев

    in.close();
    out.close();
}

我没有构建二叉树,因为输入数据已经具有二叉搜索树的充分必要条件。(每个元素都有一个左右子引用)

我没有删除节点,因为它会改变节点在向量中的位置,这样会破坏树的结构,所以在删除的时候,它只是说带有节点的子树已经被删除(bool is_delete) .

问题是这个算法在处理大量数据时不能及时运行。从 65000 个顶点开始。我不知道如何加快这个算法。为了在树中找到具有给定键的节点,您需要从根开始遍历树(您想不出更快的)O(log(n))。也许 input() 会减慢程序的速度。

c++
  • 1 个回答
  • 10 Views
Martin Hope
artem_tmm
Asked: 2020-04-30 19:39:56 +0000 UTC

如何从字符串中分别提取整数和字符

  • 0

在文本文件“8 9 + 1 7 - *”中有一行。例如,如何从字符串中获取整数并将它们放入堆栈?然后对付他们。并且字符是单独接收的。如果我只能逐个字符地获取字符串。而如果我的字符串中有两位数或更多的数字,例如876,那么它会被分解成字符8 7 6,我将无法正常提取它。


#include <string>
#include <iostream>
#include <fstream>
#include <vector>
#include <stack>
#include <deque>
#include <algorithm>
#include <utility>
#include <iterator>
#include <cstdio>


using namespace std;


int main(){

    ifstream in("input.txt");
    ofstream out("output.txt");

    stack <int> st;

    int value, i = 0;
    char ch;

    string str;

    while (!in.eof()) {
        getline(in,str); // получил строку
    }

    for (int i = 0; i < str.length(); i++) {
        ......// бегаю по ней. Могу только получать по одному символу
    }



    //или без строки сразу на прямую из файла 2-ой способ

    while(!in.eof()){
         if(in >> value){
              st.push(value);
          }

         if(!in.eof){
             in.clear();
             in.unget();

             in >> ch;

         }
    }

   // так получается, но всегда когда числовая последовательность прекращается приходится отчищать 
//поток и переходить в начало потока, из-за этого получается очень медленно,
// а у меня в задаче стоит ограничение по времени.


}
c++
  • 1 个回答
  • 10 Views

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    我看不懂措辞

    • 1 个回答
  • Marko Smith

    请求的模块“del”不提供名为“default”的导出

    • 3 个回答
  • Marko Smith

    "!+tab" 在 HTML 的 vs 代码中不起作用

    • 5 个回答
  • Marko Smith

    我正在尝试解决“猜词”的问题。Python

    • 2 个回答
  • Marko Smith

    可以使用哪些命令将当前指针移动到指定的提交而不更改工作目录中的文件?

    • 1 个回答
  • Marko Smith

    Python解析野莓

    • 1 个回答
  • Marko Smith

    问题:“警告:检查最新版本的 pip 时出错。”

    • 2 个回答
  • Marko Smith

    帮助编写一个用值填充变量的循环。解决这个问题

    • 2 个回答
  • Marko Smith

    尽管依赖数组为空,但在渲染上调用了 2 次 useEffect

    • 2 个回答
  • Marko Smith

    数据不通过 Telegram.WebApp.sendData 发送

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5