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

焦作会计做继续教育在哪个网站进口跨境电商平台排名

焦作会计做继续教育在哪个网站,进口跨境电商平台排名,做公考题的网站,wordpress怎么添加自动推送代码VTK(Visualization Toolkit)是一个开源的软件系统,用于三维计算机图形学、图像处理和可视化。它提供了丰富的工具和类来处理三维数据和交互。在 VTK 中,拾取操作通常通过 vtkCellPicker 或 vtkPointPicker 等类来实现。 本文将展示…

        VTK(Visualization Toolkit)是一个开源的软件系统,用于三维计算机图形学、图像处理和可视化。它提供了丰富的工具和类来处理三维数据和交互。在 VTK 中,拾取操作通常通过 vtkCellPicker 或 vtkPointPicker 等类来实现。

        本文将展示如何使用 vtkCellPicker 来拾取点,并判断该点是否在多个嵌套的封闭区域内。如果存在多个包含该点的封闭区域,我们将选择离拾取点最近的那个区域。之后可对选择区域进行平移操作。

实现步骤

1. 定义自定义交互器样式

        首先,我们需要定义一个自定义的交互器样式类vtkCustomInteractorStyle,继承自 vtkInteractorStyleTrackballCamera。这个类将处理鼠标点击和移动事件。

vtkCustomInteractorStyle.h 

#ifndef VTKCUSTOMINTERACTORSTYLE_H
#define VTKCUSTOMINTERACTORSTYLE_H#include <vtkInteractorStyleTrackballCamera.h>
#include <vector>
#include <vtkPoints.h>
#include <vtkActor.h>
#include <vtkSmartPointer.h>class vtkCustomInteractorStyle : public vtkInteractorStyleTrackballCamera
{
public:static vtkCustomInteractorStyle* New();vtkTypeMacro(vtkCustomInteractorStyle, vtkInteractorStyleTrackballCamera);//左键按下virtual void OnLeftButtonDown() override;//左键抬起virtual void OnLeftButtonUp() override;//右键按下virtual void OnRightButtonDown() override;//右键抬起virtual void OnRightButtonUp() override;//鼠标移动virtual void OnMouseMove() override;protected://构造函数vtkCustomInteractorStyle();//析构~vtkCustomInteractorStyle();private://将选取的屏幕点转为世界坐标double* ComputeWorldPosition(int x, int y);//使用射线法判断点是否在任意多边形内bool IsPointInPolygon(double* point, const std::vector<double*> &polygonPoints);//获取Actor的顶点void GetActorVertices(vtkSmartPointer<vtkActor> actor, std::vector<double*> &polygonPoints);//更新Actor的顶点void UpdateActorPoints(vtkSmartPointer<vtkActor> actor, double dx, double dy);//计算点与多边形顶点的的距离double ComputeDistanceToPolygon(double* point, const std::vector<double*> &polygonPoints);private:vtkSmartPointer<vtkActor> SelectedActor;double InitialPosition[3];double InitialActorPosition[3];double dx;double dy;
};#endif // VTKCUSTOMINTERACTORSTYLE_H

2. 实现自定义交互器样式

接下来,我们实现自定义交互器样式类中的各个方法。

vtkCustomInteractorStyle.cpp

#include "vtkCustomInteractorStyle.h"
#include <vtkObjectFactory.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkCellPicker.h>
#include <vtkPolyDataMapper.h>
#include <vtkPolyData.h>
#include <vtkRenderer.h>
#include <vtkProperty.h>
#include <vtkTransform.h>
#include <vtkTransformPolyDataFilter.h>vtkStandardNewMacro(vtkCustomInteractorStyle);vtkCustomInteractorStyle::vtkCustomInteractorStyle()
{
}vtkCustomInteractorStyle::~vtkCustomInteractorStyle()
{
}void vtkCustomInteractorStyle::OnLeftButtonDown()
{this->SelectedActor = nullptr;dx = 0;dy = 0;int x, y;this->GetInteractor()->GetEventPosition(x, y);double* pickPosition = this->ComputeWorldPosition(x, y);//获取所有ActorvtkSmartPointer<vtkPropCollection> actors = this->CurrentRenderer->GetActors();actors->InitTraversal();vtkSmartPointer<vtkActor> actor = nullptr;vtkSmartPointer<vtkActor> closestActor = nullptr;double minDistance = std::numeric_limits<double>::max();while ((actor = dynamic_cast<vtkActor*>(actors->GetNextProp()))){std::vector<double*> polygonPoints;GetActorVertices(actor, polygonPoints);if (IsPointInPolygon(pickPosition, polygonPoints)){double distance = ComputeDistanceToPolygon(pickPosition, polygonPoints);if (distance < minDistance){minDistance = distance;closestActor = actor;}}// 释放动态分配的内存for (const auto& point : polygonPoints){delete[] point;}polygonPoints.clear();}if (closestActor){this->SelectedActor = closestActor;this->InitialPosition[0] = pickPosition[0];this->InitialPosition[1] = pickPosition[1];this->InitialActorPosition[0] = this->SelectedActor->GetPosition()[0];this->InitialActorPosition[1] = this->SelectedActor->GetPosition()[1];}return;
}void vtkCustomInteractorStyle::OnLeftButtonUp()
{if (this->SelectedActor){UpdateActorPoints(this->SelectedActor, dx, dy);this->SelectedActor = nullptr;}return;
}void vtkCustomInteractorStyle::OnRightButtonDown()
{return;
}void vtkCustomInteractorStyle::OnRightButtonUp()
{return;
}void vtkCustomInteractorStyle::OnMouseMove()
{if (this->SelectedActor){int x, y;this->GetInteractor()->GetEventPosition(x, y);double* pickPosition = this->ComputeWorldPosition(x, y);dx = pickPosition[0] - this->InitialPosition[0];dy = pickPosition[1] - this->InitialPosition[1];this->SelectedActor->SetPosition(this->InitialActorPosition[0] + dx, this->InitialActorPosition[1] + dy, 0.0);this->Interactor->Render();}this->Superclass::OnMouseMove();
}double* vtkCustomInteractorStyle::ComputeWorldPosition(int x, int y)
{vtkSmartPointer<vtkCellPicker> picker = vtkSmartPointer<vtkCellPicker>::New();picker->SetTolerance(0.01);picker->Pick(x, y, 0, this->CurrentRenderer);return picker->GetPickPosition();
}bool vtkCustomInteractorStyle::IsPointInPolygon(double* point, const std::vector<double*> &polygonPoints)
{double x = point[0];double y = point[1];int n = polygonPoints.size();bool inside = false;for (int i = 0, j = n - 1; i < n; j = i++){double xi = polygonPoints[i][0];double yi = polygonPoints[i][1];double xj = polygonPoints[j][0];double yj = polygonPoints[j][1];bool intersect = ((yi > y) != (yj > y)) && (x < (xj - xi) * (y - yi) / (yj - yi) + xi);if (intersect){inside = !inside;}}return inside;
}void vtkCustomInteractorStyle::GetActorVertices(vtkSmartPointer<vtkActor> actor, std::vector<double*> &polygonPoints)
{vtkSmartPointer<vtkPolyDataMapper> mapper = dynamic_cast<vtkPolyDataMapper*>(actor->GetMapper());if (!mapper) return;vtkSmartPointer<vtkPolyData> polyData = mapper->GetInput();if (!polyData) return;vtkSmartPointer<vtkPoints> points = polyData->GetPoints();if (!points) return;for (vtkIdType i = 0; i < points->GetNumberOfPoints(); ++i){double point[3] = {0.0};points->GetPoint(i, point);polygonPoints.push_back(new double[3]{point[0], point[1], point[2]});}
}void vtkCustomInteractorStyle::UpdateActorPoints(vtkSmartPointer<vtkActor> actor, double dx, double dy)
{vtkSmartPointer<vtkPolyDataMapper> mapper = dynamic_cast<vtkPolyDataMapper*>(actor->GetMapper());if (!mapper) return;vtkSmartPointer<vtkPolyData> polyData = mapper->GetInput();if (!polyData) return;vtkSmartPointer<vtkPoints> points = polyData->GetPoints();if (!points) return;for (vtkIdType i = 0; i < points->GetNumberOfPoints(); ++i){double point[3] = {0.0};points->GetPoint(i, point);point[0] += dx;point[1] += dy;points->SetPoint(i, point);}polyData->Modified();
}double vtkCustomInteractorStyle::ComputeDistanceToPolygon(double* point, const std::vector<double*> &polygonPoints)
{double x = point[0];double y = point[1];double minDistance = std::numeric_limits<double>::max();for (const auto& polyPoint : polygonPoints){double distance = std::sqrt((polyPoint[0] - x) * (polyPoint[0] - x) + (polyPoint[1] - y) * (polyPoint[1] - y));if (distance < minDistance){minDistance = distance;}}return minDistance;
}

3. 代码解释

3.1 头文件 vtkCustomInteractorStyle.h
  • 类声明:定义了一个自定义交互器样式类 vtkCustomInteractorStyle,继承自 vtkInteractorStyleTrackballCamera
  • 方法声明
    • OnLeftButtonDown:处理左键按下事件。
    • OnLeftButtonUp:处理左键抬起事件。
    • OnRightButtonDown 和 OnRightButtonUp:处理右键按下和抬起事件。
    • OnMouseMove:处理鼠标移动事件。
  • 辅助方法
    • ComputeWorldPosition:计算鼠标点击位置的世界坐标。
    • IsPointInPolygon:判断点是否在多边形内。
    • GetActorVertices:获取 Actor 的顶点。
    • UpdateActorPoints:更新 Actor 的顶点坐标。
    • ComputeDistanceToPolygon:计算点到多边形顶点的最小距离。
3.2 源文件 vtkCustomInteractorStyle.cpp
  • 构造函数和析构函数:初始化和清理类成员变量。
  • OnLeftButtonDown 方法
    • 获取鼠标点击位置的世界坐标。
    • 遍历渲染器中的所有 Actor,获取每个 Actor 的顶点。
    • 使用 IsPointInPolygon 判断拾取点是否在多边形内。
    • 如果在多边形内,使用 ComputeDistanceToPolygon 计算点到多边形顶点的最小距离,并记录离拾取点最近的 Actor。
    • 释放动态分配的内存。
    • 设置 SelectedActor 为离拾取点最近的 Actor。
  • OnLeftButtonUp 方法
    • 如果有选中的 Actor,更新其顶点坐标并重置选中状态。
  • OnRightButtonDown 和 OnRightButtonUp 方法
    • 调用父类的方法处理右键事件。
  • OnMouseMove 方法
    • 如果有选中的 Actor,根据鼠标移动更新 Actor 的位置。
  • ComputeWorldPosition 方法
    • 使用 vtkCellPicker 获取拾取点的世界坐标。
  • IsPointInPolygon 方法
    • 使用射线法判断点是否在多边形内。
  • GetActorVertices 方法
    • 获取 Actor 的顶点坐标。
  • UpdateActorPoints 方法
    • 更新 Actor 的顶点坐标。
  • ComputeDistanceToPolygon 方法
    • 计算点到多边形顶点的最小距离。

4. 使用自定义交互器样式

最后,我们需要在主程序中使用自定义的交互器样式。

首先在QT界面中嵌套VTK窗口,详情见VTK随笔一:初识VTK(QT中嵌入VTK窗口)-CSDN博客

主要代码:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <vtkSmartPointer.h>
#include <vtkPoints.h>
#include <vtkCellArray.h>
#include <vtkPolyData.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkNamedColors.h>
#include <vtkRegularPolygonSource.h>
#include <vtkCellPicker.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkCommand.h>
#include <vtkCallbackCommand.h>
#include <vtkLine.h>
#include <vtkProperty.h>
#include <vtkGenericOpenGLRenderWindow.h>
#include <vtkCamera.h>
#include "vtkCustomInteractorStyle.h"MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);vtkSmartPointer<vtkNamedColors> colors = vtkSmartPointer<vtkNamedColors>::New();// 创建矩形的点集vtkSmartPointer<vtkPoints> rectanglePoints = vtkSmartPointer<vtkPoints>::New();rectanglePoints->InsertNextPoint(0.0, 0.0, 0.0); // 左下角rectanglePoints->InsertNextPoint(1.0, 0.0, 0.0); // 右下角rectanglePoints->InsertNextPoint(1.0, 1.0, 0.0); // 右上角rectanglePoints->InsertNextPoint(0.0, 1.0, 0.0); // 左上角// 创建矩形的线段vtkSmartPointer<vtkCellArray> rectangleLines = vtkSmartPointer<vtkCellArray>::New();vtkSmartPointer<vtkLine> line = vtkSmartPointer<vtkLine>::New();// 左下角到右下角line->GetPointIds()->SetId(0, 0);line->GetPointIds()->SetId(1, 1);rectangleLines->InsertNextCell(line);// 右下角到右上角line->GetPointIds()->SetId(0, 1);line->GetPointIds()->SetId(1, 2);rectangleLines->InsertNextCell(line);// 右上角到左上角line->GetPointIds()->SetId(0, 2);line->GetPointIds()->SetId(1, 3);rectangleLines->InsertNextCell(line);// 左上角到左下角line->GetPointIds()->SetId(0, 3);line->GetPointIds()->SetId(1, 0);rectangleLines->InsertNextCell(line);// 创建矩形的PolyDatavtkSmartPointer<vtkPolyData> rectanglePolyData = vtkSmartPointer<vtkPolyData>::New();rectanglePolyData->SetPoints(rectanglePoints);rectanglePolyData->SetLines(rectangleLines);// 创建矩形的MappervtkSmartPointer<vtkPolyDataMapper> rectangleMapper = vtkSmartPointer<vtkPolyDataMapper>::New();rectangleMapper->SetInputData(rectanglePolyData);// 创建矩形的ActorvtkSmartPointer<vtkActor> rectangleActor = vtkSmartPointer<vtkActor>::New();rectangleActor->SetMapper(rectangleMapper);rectangleActor->GetProperty()->SetColor(colors->GetColor3d("Tomato").GetData());// 创建圆形vtkSmartPointer<vtkRegularPolygonSource> circleSource = vtkSmartPointer<vtkRegularPolygonSource>::New();circleSource->SetNumberOfSides(100); // 多边形近似圆形circleSource->SetRadius(0.5);circleSource->SetCenter(2.0, 0.5, 0.0);circleSource->SetNormal(0.0, 0.0, 1.0);// 创建圆形的MappervtkSmartPointer<vtkPolyDataMapper> circleMapper = vtkSmartPointer<vtkPolyDataMapper>::New();circleMapper->SetInputConnection(circleSource->GetOutputPort());// 创建圆形的ActorvtkSmartPointer<vtkActor> circleActor = vtkSmartPointer<vtkActor>::New();circleActor->SetMapper(circleMapper);circleActor->GetProperty()->SetColor(colors->GetColor3d("Cyan").GetData());// 创建嵌套的矩形vtkSmartPointer<vtkPoints> nestedRectanglePoints = vtkSmartPointer<vtkPoints>::New();nestedRectanglePoints->InsertNextPoint(1.2, 0.2, 0.0); // 左下角nestedRectanglePoints->InsertNextPoint(1.8, 0.2, 0.0); // 右下角nestedRectanglePoints->InsertNextPoint(1.8, 0.8, 0.0); // 右上角nestedRectanglePoints->InsertNextPoint(1.2, 0.8, 0.0); // 左上角// 创建嵌套矩形的线段vtkSmartPointer<vtkCellArray> nestedRectangleLines = vtkSmartPointer<vtkCellArray>::New();line = vtkSmartPointer<vtkLine>::New();// 左下角到右下角line->GetPointIds()->SetId(0, 0);line->GetPointIds()->SetId(1, 1);nestedRectangleLines->InsertNextCell(line);// 右下角到右上角line->GetPointIds()->SetId(0, 1);line->GetPointIds()->SetId(1, 2);nestedRectangleLines->InsertNextCell(line);// 右上角到左上角line->GetPointIds()->SetId(0, 2);line->GetPointIds()->SetId(1, 3);nestedRectangleLines->InsertNextCell(line);// 左上角到左下角line->GetPointIds()->SetId(0, 3);line->GetPointIds()->SetId(1, 0);nestedRectangleLines->InsertNextCell(line);// 创建嵌套矩形的PolyDatavtkSmartPointer<vtkPolyData> nestedRectanglePolyData = vtkSmartPointer<vtkPolyData>::New();nestedRectanglePolyData->SetPoints(nestedRectanglePoints);nestedRectanglePolyData->SetLines(nestedRectangleLines);// 创建嵌套矩形的MappervtkSmartPointer<vtkPolyDataMapper> nestedRectangleMapper = vtkSmartPointer<vtkPolyDataMapper>::New();nestedRectangleMapper->SetInputData(nestedRectanglePolyData);// 创建嵌套矩形的ActorvtkSmartPointer<vtkActor> nestedRectangleActor = vtkSmartPointer<vtkActor>::New();nestedRectangleActor->SetMapper(nestedRectangleMapper);nestedRectangleActor->GetProperty()->SetColor(colors->GetColor3d("Lime").GetData());// 创建渲染器并添加Actor到渲染器vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();renderer->AddActor(rectangleActor);renderer->AddActor(circleActor);renderer->AddActor(nestedRectangleActor);renderer->SetBackground(colors->GetColor3d("SlateGray").GetData());renderer->ResetCamera();// 设置自定义交互器样式vtkSmartPointer<vtkCustomInteractorStyle> style = vtkSmartPointer<vtkCustomInteractorStyle>::New();style->SetCurrentRenderer(renderer);vtkSmartPointer<vtkGenericOpenGLRenderWindow> renderWindow = vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New();renderWindow->AddRenderer(renderer);ui->widget->setRenderWindow(renderWindow);ui->widget->interactor()->SetInteractorStyle(style);// 渲染renderWindow->Render();
}MainWindow::~MainWindow()
{delete ui;
}

5. 代码解释

5.1 创建几何对象
  • 矩形:使用 vtkPoints 和 vtkCellArray 创建矩形的顶点和线段。
  • 圆形:使用 vtkRegularPolygonSource 创建一个近似的圆形。
  • 嵌套矩形:创建一个嵌套在矩形内的较小矩形。
5.2 创建Mapper和Actor
  • 矩形:将 vtkPolyData 设置到 vtkPolyDataMapper 中,然后将 vtkPolyDataMapper 设置到 vtkActor 中。
  • 圆形:将 vtkRegularPolygonSource 的输出设置到 vtkPolyDataMapper 中,然后将 vtkPolyDataMapper 设置到 vtkActor 中。
  • 嵌套矩形:将 vtkPolyData 设置到 vtkPolyDataMapper 中,然后将 vtkPolyDataMapper 设置到 vtkActor 中。
5.3 设置Actor的名称
  • 为每个 Actor 设置名称,方便调试和识别。
5.4 添加Actor到渲染器
  • 将所有 Actor 添加到渲染器中,并设置背景颜色。
5.5 渲染并启动交互
  • 渲染场景并启动交互器,使用户可以通过鼠标进行操作。

6. 运行效果

        运行上述代码后,你将看到一个包含矩形、圆形和嵌套矩形的 3D 场景。当你点击场景中的某个点时,程序会判断该点是否在多个封闭区域内,并选择离拾取点最近的那个区域。选中的区域将被移动,以响应鼠标移动事件。

7. 总结

        本文介绍了如何在 VTK 中实现拾取点并获取离拾取点最近的包含该点的封闭区域。通过定义自定义交互器样式类 vtkCustomInteractorStyle,我们可以处理鼠标点击和移动事件,并使用 vtkCellPicker 获取拾取点的世界坐标。通过遍历所有 Actor 并计算点到多边形顶点的最小距离,我们可以准确地选择离拾取点最近的区域。

        这种方法在处理复杂的嵌套几何体时非常有用,可以确保用户选择的是最内层的区域。希望这篇文章对你在使用 VTK 进行三维图形渲染和交互有所帮助!

http://www.dtcms.com/a/464511.html

相关文章:

  • 网站登记模板搬家网站模板
  • 个人域名免费网站3d动画制作软件免费
  • 免费下载代码项目的网站汕头企业网站推广方法
  • 网站建设的布局种类建设工程建筑网
  • 医院网站建设策划案模板培训机构退费法律规定
  • 做qq图片的网站有哪些宁波城乡建设网站
  • 益阳建设局网站如何创建自己公司网站
  • 莱芜都市网人才网北京seo公司助力网络营销
  • 郑州网站制作公司汉狮宁波随身云网络科技有限公司
  • 自己如何建设刷赞网站线下推广的好处
  • 广告网站建设案例南浔住房和城乡建设局网站
  • 公司网站建设功能介绍做收费网站
  • 安阳网站制作优化android 网站模板
  • 温州建站软件旅游业网站开发建设
  • 可以免费注册网站站内免费推广
  • 做外包哪个网站好一些优秀的摄影作品网站
  • 淮安市建设局网站网上做兼职的网站
  • 像做网站平台取什么名字好青岛建站行业
  • 泉州自助建站在线音乐网站 用什么做
  • 网站 弹出网站开发背景400字
  • 传统网站模板建站 公司
  • 城市门户网站哪里可以免费建网站
  • 唐山营销型网站制作学做投资网站好
  • 怎样做关键词网站连接一般通过什么意思
  • 如何做淘宝联盟网站的推广网站建设排名软件
  • 佛山市南海建设局网站dw wordpress
  • 电影网站做流量温州网站建设温州网站制作
  • 微信官方网站登陆手工制作灯笼的步骤
  • 网站建设资料宁波网络推广渠道有哪些
  • 陕西建设网综合便民服务中心网站短视频运营岗位职责