两个vtkLineWidget2重合显示z-index的问题

40 篇文章 7 订阅

需求:

两个vtkLineWidget2颜色不一样,需要将选中的vtkLineWidget2显示在上层,

默认按照vtkLineWidget2创建顺序显示,即后创建的覆盖在先创建的上面。

解决:

修改Point1WorldPosition 和Point2WorldPosition的z坐标值

double zIndexDown = 0.0;
double zIndexTop = 0.1;

代码:

#include <vtkActor.h>
#include <vtkCamera.h>
#include <vtkCommand.h>
#include <vtkLineRepresentation.h>
#include <vtkLineWidget2.h>
#include <vtkNamedColors.h>
#include <vtkNew.h>
#include <vtkPolyData.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkSphereSource.h>

#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkInteractionStyle)
VTK_MODULE_INIT(vtkRenderingFreeType)
VTK_MODULE_INIT(vtkRenderingOpenGL2)
VTK_MODULE_INIT(vtkRenderingVolumeOpenGL2)

namespace {

vtkNew<vtkLineWidget2> lineWidget;
vtkNew<vtkLineWidget2> lineWidget2;
double zIndex = 0.0;
double zIndexTop = 0.1;
// This does the actual work.
// Callback for the interaction
class vtkLineCallback : public vtkCommand {
 public:
  static vtkLineCallback* New() { return new vtkLineCallback; }

  virtual void Execute(vtkObject* caller, unsigned long, void*) {
    vtkLineWidget2* lineWidget = reinterpret_cast<vtkLineWidget2*>(caller);

    bool isSecond = false;
    if (lineWidget2 == lineWidget) {
      isSecond = true;
    }

    // Get the actual box coordinates of the line
    vtkNew<vtkPolyData> polydata;
    static_cast<vtkLineRepresentation*>(lineWidget->GetRepresentation())
        ->GetPolyData(polydata);

    // Display one of the points, just so we know it's working
    double p[3];
    polydata->GetPoint(0, p);

    std::cout << "is second:" << isSecond << "\n";
    std::cout << "P: " << p[0] << " " << p[1] << " " << p[2] << std::endl;
    double Point1WorldPosition[3];
    static_cast<vtkLineRepresentation*>(lineWidget->GetRepresentation())
        ->GetPoint1WorldPosition(Point1WorldPosition); 
    double Point2WorldPosition[3];
    static_cast<vtkLineRepresentation*>(lineWidget->GetRepresentation())
        ->GetPoint2WorldPosition(Point2WorldPosition);
    std::cout << "Point1WorldPosition: " << Point1WorldPosition[0] << " "
              << Point1WorldPosition[1] << " " << Point1WorldPosition[2]
              << std::endl;
    if (isSecond) {
      Point1WorldPosition[2] = zIndex;
      Point2WorldPosition[2] = zIndex;
    }
    else {
      Point1WorldPosition[2] = zIndexTop;
      Point2WorldPosition[2] = zIndexTop;
    }
    static_cast<vtkLineRepresentation*>(
        lineWidget->GetRepresentation())
        ->SetPoint1WorldPosition(Point1WorldPosition);
    static_cast<vtkLineRepresentation*>(lineWidget->GetRepresentation())
        ->SetPoint2WorldPosition(Point2WorldPosition);
    std::cout << "Point1WorldPosition set: " << Point1WorldPosition[0] << " "
              << Point1WorldPosition[1] << " "
              << Point1WorldPosition[2] << std::endl;
  }
  vtkLineCallback() {}
};
}  // namespace

int main(int, char* []) {
  vtkNew<vtkNamedColors> colors;

  vtkNew<vtkSphereSource> sphereSource;
  sphereSource->SetRadius(.4);
  sphereSource->Update();

  // Create a mapper and actor
  vtkNew<vtkPolyDataMapper> mapper;
  mapper->SetInputConnection(sphereSource->GetOutputPort());
  vtkNew<vtkActor> actor;
  actor->SetMapper(mapper);
  actor->GetProperty()->SetColor(colors->GetColor3d("MistyRose").GetData());

  // A renderer and render window
  vtkNew<vtkRenderer> renderer;
  vtkNew<vtkRenderWindow> renderWindow;
  renderWindow->AddRenderer(renderer);
  renderWindow->SetWindowName("LineWidget2");

  renderer->AddActor(actor);
  renderer->SetBackground(colors->GetColor3d("MidnightBlue").GetData());

  // An interactor
  vtkNew<vtkRenderWindowInteractor> renderWindowInteractor;
  renderWindowInteractor->SetRenderWindow(renderWindow);

  // vtkNew<vtkLineWidget2> lineWidget;
  vtkNew<vtkLineRepresentation> lineRep;
  lineRep->SetLineColor(0, 1, 0);
  lineWidget->SetRepresentation(lineRep);
  lineWidget->SetInteractor(renderWindowInteractor);
  // lineWidget->CreateDefaultRepresentation();

  // vtkNew<vtkLineWidget2> lineWidget

结果:

绿色在红色上面

红色在绿色上面:

要求取两个Subdiv2D对象重合的面积,可以使用OpenCvSharp中的Subdiv2D.Intersect()方法。该方法可以求取两个三角形的交集。 具体来说,可以先构建两个Subdiv2D对象,然后将它们分别细分成更小的三角形,并对所有三角形进行遍历,找到在两个Subdiv2D中都存在的三角形,然后计算它们的交集面积。 以下是一个示例代码: ``` using OpenCvSharp; // 创建两个点集 var points1 = new Point2f[] { new Point2f(10, 10), new Point2f(100, 10), new Point2f(10, 100), new Point2f(100, 100) }; var points2 = new Point2f[] { new Point2f(50, 50), new Point2f(150, 50), new Point2f(50, 150), new Point2f(150, 150) }; // 创建两个Subdiv2D对象 var subdiv1 = new Subdiv2D(); var subdiv2 = new Subdiv2D(); // 将点集中的点插入到Subdiv2D中 foreach (var point in points1) { subdiv1.Insert(point); } foreach (var point in points2) { subdiv2.Insert(point); } // 获取两个Subdiv2D对象中的所有三角形 var triangles1 = subdiv1.GetTriangleList(); var triangles2 = subdiv2.GetTriangleList(); double totalArea = 0; // 遍历两个Subdiv2D对象中的所有三角形 foreach (var triangle1 in triangles1) { foreach (var triangle2 in triangles2) { // 判断两个三角形是否有交集 if (subdiv1.Intersect(triangle1.ToArray(), subdiv2, triangle2.ToArray())) { // 计算交集面积,并累加到总面积中 var intersection = subdiv1.GetTriangleIntersection(triangle1.ToArray(), triangle2.ToArray()); totalArea += Cv2.ContourArea(intersection); } } } Console.WriteLine("重合面积为:" + totalArea); ``` 以上代码将创建两个点集,然后将它们分别插入到两个Subdiv2D对象中,并对所有三角形进行遍历,找到在两个Subdiv2D中都存在的三角形,然后计算它们的交集面积,并将所有交集面积累加到总面积中。最后输出重合面积。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值