二维曲线旋转形成三维曲面


开发环境:

  1. Windows 11 家庭中文版
  2. Microsoft Visual Studio Community 2019
  3. VTK-9.3.0.rc0
  4. vtk-example

demo解决问题:创建一个带有盖的球体的可视化图形。程序通过将一个二维曲线沿着y轴旋转,形成三维曲面,从而实现这一目标。

在这里插入图片描述

关键点:

  1. 程序接受命令行参数来自定义可视化效果。这些参数包括弧的角度、旋转步长和弧的半径。另外,还可以选择使用可选参数来取消球体的盖子或者显示用于生成曲面的旋转曲线。
  auto pts = GetLine(angle, step, radius, uncapped, start);

  // Setup points and lines
  vtkNew<vtkPoints> points;
  vtkNew<vtkCellArray> lines;
  for (auto pt : pts)
  {
    unsigned long pt_id = points->InsertNextPoint(pt.data());
    if (pt_id < pts.size() - 1)
    {
      vtkNew<vtkLine> line;
      line->GetPointIds()->SetId(0, pt_id);
      line->GetPointIds()->SetId(1, pt_id + 1);
      lines->InsertNextCell(line);
    }
  }
  1. 主要函数处理命令行参数,将角度转换为弧度,并利用VTK库设置可视化效果。它通过生成沿着弧的点来创建曲线,然后使用旋转成型来生成带有盖的球体。最终的可视化效果通过VTK的渲染功能在窗口中显示出来。
  // Extrude the profile to make the capped sphere
  vtkNew<vtkRotationalExtrusionFilter> extrude;
  extrude->SetInputData(polydata);
  extrude->SetResolution(60);

  1. 辅助函数:用于根据指定的角度、步长和半径构造曲线上的点。
std::vector<std::array<double, 3>>
GetLine(double const& angle, double const& step, double const& radius,
        bool const& uncapped, double const& start)

prj name: CappedSphere

#include <vtkActor.h>
#include <vtkCamera.h>
#include <vtkCellArray.h>
#include <vtkLine.h>
#include <vtkNamedColors.h>
#include <vtkNew.h>
#include <vtkPoints.h>
#include <vtkPolyData.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkRotationalExtrusionFilter.h>

#include <array>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <regex>
#include <sstream>
#include <string>
#include <vector>

namespace {
/**
 * Get the points for a line.
 *
 * @param angle: Length of the arc in degrees.
 * @param step: Step size in degrees.
 * @param radius: Radius of the arc.
 * @param uncapped: True if uncapped.
 * @param start: Starting angle.
 * @return: A vector of points.
 */
std::vector<std::array<double, 3>>
GetLine(double const& angle, double const& step, double const& radius,
        bool const& noCap, double const& start);

/**
 * Show the command line parameters.
 *
 * @param fn: The program name.
 */
std::string ShowUsage(std::string fn);

} // namespace

int main(int argc, char* argv[])
{
  // Our degree/radian conversions
  constexpr auto pi = 3.141592653589793238462643383279502884L; /* pi */
  auto d_r = [pi](long double d) { return pi * d / 180.0; };
  // auto r_d = [pi](long double r) { return 180 * r / pi; };
  auto isNumber = [](std::string const& token) {
    return std::regex_match(
        token, std::regex(("((\\+|-)?[[:digit:]]+)(\\.(([[:digit:]]+)?))?")));
  };

  auto angle = 90.0;
  auto step = 1.0;
  auto radius = 1.0;
  auto uncapped = false;
  auto showLine = false;

  // The command line arguments
  std::vector<std::string> cmdVec;
  for (auto i = 1; i < argc; ++i)
  {
    cmdVec.push_back(argv[i]);
  }
  if (!cmdVec.empty())
  {
    // Look for parameters
    auto posCnt = 0;
    for (auto const& token : cmdVec)
    {
      if (token == "-h" || token == "--help")
      {
        std::cout << ShowUsage(argv[0]) << std::endl;
        return EXIT_SUCCESS;
      }
      if (token == "-u" || token == "--uncapped")
      {
        uncapped = true;
      }
      if (token == "-s" || token == "--show_line")
      {
        showLine = true;
      }
      if (isNumber(token) && posCnt < 3)
      {
        switch (posCnt)
        {
        case 0:
          angle = std::stod(token);
          break;
        case 1:
          step = std::stod(token);
          break;
        case 2:
          radius = std::stod(token);
          break;
        default:
          break;
        }
        posCnt++;
      }
    }
  }
  angle = d_r(std::abs(angle));
  step = d_r(std::abs(step));
  radius = std::abs(radius);
  // With default settings set this to 45 and you get a bowl with a flat bottom.
  auto start = d_r(90);

  auto pts = GetLine(angle, step, radius, uncapped, start);

  // Setup points and lines
  vtkNew<vtkPoints> points;
  vtkNew<vtkCellArray> lines;
  for (auto pt : pts)
  {
    unsigned long pt_id = points->InsertNextPoint(pt.data());
    if (pt_id < pts.size() - 1)
    {
      vtkNew<vtkLine> line;
      line->GetPointIds()->SetId(0, pt_id);
      line->GetPointIds()->SetId(1, pt_id + 1);
      lines->InsertNextCell(line);
    }
  }

  vtkNew<vtkPolyData> polydata;
  polydata->SetPoints(points);
  polydata->SetLines(lines);

  // Extrude the profile to make the capped sphere
  vtkNew<vtkRotationalExtrusionFilter> extrude;
  extrude->SetInputData(polydata);
  extrude->SetResolution(60);

  //  Visualize
  vtkNew<vtkNamedColors> colors;

  // To see the line
  vtkNew<vtkPolyDataMapper> lineMapper;
  lineMapper->SetInputData(polydata);

  vtkNew<vtkActor> lineActor;
  lineActor->SetMapper(lineMapper);
  lineActor->GetProperty()->SetLineWidth(4);
  lineActor->GetProperty()->SetColor(colors->GetColor3d("Red").GetData());

  // To see the surface
  vtkNew<vtkPolyDataMapper> surfaceMapper;
  surfaceMapper->SetInputConnection(extrude->GetOutputPort());

  vtkNew<vtkActor> surfaceActor;
  surfaceActor->SetMapper(surfaceMapper);
  surfaceActor->GetProperty()->SetColor(colors->GetColor3d("Khaki").GetData());

  vtkNew<vtkRenderer> ren;
  vtkNew<vtkRenderWindow> renWin;
  renWin->AddRenderer(ren);
  vtkNew<vtkRenderWindowInteractor> iren;
  iren->SetRenderWindow(renWin);

  ren->AddActor(surfaceActor);
  if (showLine)
  {
    ren->AddActor(lineActor);
  }
  ren->SetBackground(colors->GetColor3d("LightSlateGray").GetData());

  ren->ResetCamera();
  ren->GetActiveCamera()->Azimuth(0);
  ren->GetActiveCamera()->Elevation(60);
  ren->ResetCameraClippingRange();

  renWin->SetSize(600, 600);
  renWin->Render();
  renWin->SetWindowName("CappedSphere");
  iren->Start();

  return EXIT_SUCCESS;
}

namespace {

std::vector<std::array<double, 3>>
GetLine(double const& angle, double const& step, double const& radius,
        bool const& uncapped, double const& start)
{
  auto constexpr precision = 1.0e-06;
  std::vector<std::array<double, 3>> pts;
  // Do the curved line
  auto theta = 0.0;
  while (theta <= angle)
  {
    std::array<double, 3> p{{0.0, 0.0, 0.0}};
    p[0] = radius * std::cos(start - theta);
    p[2] = radius * std::sin(theta - start);
    if (p[0] < 0)
    {
      p[0] = 0;
      pts.push_back(p);
      break;
    }
    if (std::abs(p[0]) < precision)
    {
      p[0] = 0;
    }
    if (std::abs(p[2]) < precision)
    {
      p[2] = 0;
    }
    pts.push_back(p);
    theta += step;
  }
  if (!uncapped)
  {
    // Drop a perpendicular from the last point to the x-axis
    if (pts.size() > 1)
    {
      std::array<double, 3> lastPoint = pts.back();
      if (lastPoint[0] > 0)
      {
        auto numPts = 10;
        auto interval = double(numPts) / radius;
        auto i = 1;
        while (i < numPts)
        {
          std::array<double, 3> p{{0.0, 0.0, lastPoint[2]}};
          p[0] = lastPoint[0] - i / interval;
          if (p[0] < 0)
          {
            p[0] = 0;
            pts.push_back(p);
            break;
          }
          if (std::abs(p[0]) < precision)
          {
            p[0] = 0;
          }
          if (std::abs(p[2]) < precision)
          {
            p[2] = 0;
          }
          pts.push_back(p);
          ++i;
        }
      }
      lastPoint = pts.back();
      if (lastPoint[0] > precision)
      {
        std::array<double, 3> p{{0.0, 0.0, lastPoint[2]}};
        pts.push_back(p);
      }
    }
  }
  return pts;
}

std::string ShowUsage(std::string fn)
{
  // Remove the folder (if present) then emove the extension in this order
  // since the folder name may contain perionds.
  auto last_slash_idx = fn.find_last_of("\\/");
  if (std::string::npos != last_slash_idx)
  {
    fn.erase(0, last_slash_idx + 1);
  }
  // auto period_idx = fn.rfind('.');
  // if (std::string::npos != period_idx)
  //{
  //  fn.erase(period_idx);
  //}
  std::ostringstream os;
  os << "\nusage: " << fn << " [-h] [-u] [-s] [angle] [step] [radius]\n";
  os << "\n";
  os << "Display a capped sphere.\n";
  os << "\n";
  os << "positional arguments:\n";
  os << "  angle            The length of the arc in degrees from +z to -z in "
        "the +x\n";
  os << "                   direction in the x-z plane.\n";
  os << "  step             Step size in degrees.\n";
  os << "  radius           Radius of the arc.\n";
  os << "\n";
  os << "optional arguments:\n";
  os << "  -h, --help       show this help message and exit\n";
  os << "  -u, --uncapped   Uncap the sphere.\n";
  os << "  -s, --show_line  Show the line that is rotationally extruded to "
        "make the\n";
  os << "                   surface.";
  os << std::endl;
  return os.str();
}

} // namespace

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/373907.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux第42步_移植ST公司uboot的第3步_uboot命令测试,搭建nfs服务器和tftp服务器

测试uboot命令&#xff0c;搭建nfs服务器和tftp服务器&#xff0c;是测试uboot非常关键的一步。跳过这一节&#xff0c;后面可能要踩坑。 一、输入“help回车”&#xff0c;查询uboot所支持的命令 二、输入“? bootz回车”&#xff0c;查询“bootz”怎么用 注意&#xff1a;和…

ELFK日志采 - QuickStart

文章目录 架构选型ELKEFLK ElasticsearchES集群搭建常用命令 Filebeat功能介绍安装步骤Filebeat配置详解filebeat常用命令 Logstash功能介绍安装步骤Input插件Filter插件Grok Filter 插件Mutate Filter 插件常见的插件配置选项&#xff1a;Mutate Filter配置案例&#xff1a; O…

HarmonyOS开发工具DevEco Studio安装以及汉化

HUAWEI DevEco Studio 面向HarmonyOS应用及元服务开发者提供的集成开发环境(IDE)&#xff0c; 助力高效开发。 应用内共享HSP开发 支持在Stage模型和模块化编译方式下开发HSP&#xff0c;以及共享HSP给应用内其他模块使用;支持运行态共享HSP。Code Linter代码检查 支持ArkTS/T…

ArcGIS制图问题——标注和符号压盖

水文站网的站点&#xff08;包括水文站、水位站、雨量站、水质站、地下水站、墒情站等&#xff09;名称基本是以所在的村命名&#xff0c;如果在这个村有多个站点&#xff0c;造成了站点名称压盖的情况&#xff0c;如图&#xff1a; 该问题多个点要素图层标注重复&#xff0c;…

滑动窗口经典问题(算法村第十六关白银挑战)

最长字串专题 无重复字符的最长子串 3. 无重复字符的最长子串 - 力扣&#xff08;LeetCode&#xff09; 给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的 最长子串 的长度。 示例 1: 输入: s "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是…

Stable Diffusion 模型下载:RealCartoon3D - V14

文章目录 模型介绍生成案例案例一案例二案例三案例四案例五案例六案例七案例八案例九案例十下载地址模型介绍 RealCartoon3D 是一个动漫卡通混合现实风格的模型,具有真实卡通的 3D 效果,当前更新到 V14 版本。 RealCartoon3D 是我上传的第一个模型。我仍在学习这些东西,但…

有趣的CSS - 按钮文字上下滑动

目录 整体效果核心代码html 代码css 部分代码 完整代码如下html 页面css 样式页面渲染效果 整体效果 这个按钮效果主要使用 :hover 伪选择器以及 transition 过渡属性来实现两个子元素上下过渡的效果。 此效果可以在主入口按钮、详情或者更多等按钮处使用&#xff0c;增加一些鼠…

Protainer

Protainer 介绍 Portainer 是一款轻量级的应用&#xff0c;它提供了图形化界面&#xff0c;用于方便地管理Docker环境&#xff0c;包括单机环境和集群环境。 官网 protainer 安装 docker run -d -p 8000:8000 -p 9000:9000 --name portainer --restartalways -v /var/r…

【Linux】Linux权限(下)

Hello everybody!在上一篇文章中&#xff0c;权限讲了大部分内容。今天继续介绍权限剩下的内容&#xff0c;希望大家看过这篇文章后都能有所收获&#xff01; 1.更改文件的拥有者和所属组 对于普通用户&#xff0c;文件的拥有者和所属组都无权修改。 、 、 但root可以修改文件…

嵌入式软件设计方式与方法

1、嵌入式软件与设计模式 思从深而行从简 软件开发&#xff0c;难的不是编写软件&#xff0c;而是编写功能正常的软件。软件工程化才能保证软件质量和项目进度&#xff0c;而设计模式使代码开发真正工程化&#xff0c;设计模式是软件工程的基石。 所谓设计模式就是对常见问题的…

【django】建立python虚拟环境-20240205

1.确保已经安装pip3 install venv 2.新建虚拟环境 python -m venv myenv 3.安装虚拟环境的依赖包 pip install … 4.激活虚拟环境 cd myenv cd Scripts activate 激活activate.bat并进入虚拟环境 进入虚拟环境后&#xff0c;命令行前面显示&#xff08;myenv&#xff0…

第二证券:风电景气度持续向好 诺和诺德推动减肥药扩产

昨日&#xff0c;两市股指早盘大幅下探&#xff0c;沪指盘中跌超3%创近5年新低&#xff0c;深成指、创业板指一度跌超4%&#xff0c;均创本轮调整新低&#xff1b;午后&#xff0c;三大股指在金融、酿酒等板块的带动下快速拉升&#xff0c;沪指翻红重返2700点上方&#xff0c;创…

【openwrt】MT7981 5G WiFi MAC地址不生效问题分析及解决方案

问题描述 MT7981 默认sdk 5G MAC地址根据2.4G MAC地址随机生成,我们写到Factory区域的值不生效 问题分析 查看EEPROM MAC位置 查看MTK EEPROM文档MT7981_EEPROM_Content_Introduction_V10_20211207.pdf可以看到EEPROM里面有两个位置可以存放MAC,0x04~0x09 和0x0a~0x0f 查看…

WINDOWS搭建NFS服务器

下载并安装 Networking Software for Windows 启动配置 找到安装目录&#xff08;如C:\Program Files\nfsd&#xff09;&#xff0c;双击nfsctl.exe&#xff0c;菜单Edit->Preferences 启动后&#xff1a; 配置Export Exports->Edit exports file 其他的几句我都删除…

第4节、电机多段转动【51单片机+L298N步进电机系列教程】

↑↑↑点击上方【目录】&#xff0c;查看本系列全部文章 摘要&#xff1a;本节介绍用控制步进电机三个主要参数角度、速度、方向&#xff0c;实现简单的步进电机多段控制 一、目标功能 输入多个目标角度&#xff0c;以及每个角度对应的速度&#xff0c;实现步进电机的多段多速…

C# OpenVINO 图片旋转角度检测

目录 效果 项目 代码 下载 效果 项目 代码 using OpenCvSharp; using Sdcb.OpenVINO; using System; using System.Diagnostics; using System.Drawing; using System.Linq; using System.Runtime.InteropServices; using System.Security.Cryptography; using System.Te…

讯飞星火3.5API接入指南

概述 讯飞星火大模型拥有跨领域的知识和语言理解能力&#xff0c;完成问答对话和文学创作等任务。持续从海量文本数据和大规模语法知识中学习进化&#xff0c;实现从提出问题、规划问题到解决问题的全流程闭环。 API调用流程 步骤一.资源包申请 登录讯飞星火平台&#xff0…

05-编码篇-H264文件分析

通过前面的分析&#xff0c;我们可以看出常规情况下&#xff0c;是将视频以帧的单位进行处理&#xff0c;比如I帧&#xff0c;P帧&#xff0c;B帧等。 但是这些帧是如何以文件方式保存的呢&#xff0c;这节我们主要对H264的保存方式作一个了解。 一帧图片通过编码后&#xff0c…

Matlab:利用1D-CNN(一维卷积神经网络),分析高光谱曲线数据或时序数据

1DCNN 简介&#xff1a; 1D-CNN&#xff08;一维卷积神经网络&#xff09;是一种特殊类型的卷积神经网络&#xff0c;设计用于处理一维序列数据。这种网络结构通常由多个卷积层和池化层交替组成&#xff0c;最后使用全连接层将提取的特征映射到输出。 以下是1D-CNN的主要组成…

【防止重复提交】Redis + AOP + 注解的方式实现分布式锁

文章目录 工作原理需求实现1&#xff09;自定义防重复提交注解2&#xff09;定义防重复提交AOP切面3&#xff09;RedisLock 工具类4&#xff09;过滤器 请求工具类5&#xff09;测试Controller6&#xff09;测试结果 工作原理 分布式环境下&#xff0c;可能会遇到用户对某个接…