首页/文章/ 详情

tcl调用Python实现两组节点最近距离计算

27天前浏览405

记录一下,hypermesh二次开发项目中实际遇到的问题,寻找两组节点之间的最近距离。

之前都是使用Tcl的循环加循环方式来计算最近距离。数据量小感受不出慢。但用上这个项目的数据,两组节点分别10000个,程序运行的时间复杂度为O (n^2),需要循环100,000,000次。

大力出奇迹版本

    # 定义两组3D节点的坐标set nodes1 {{1 2 3} {4 5 6} {7 8 9}}set nodes2 {{10 11 12} {13 14 15} {16 17 18}}# 计算两组节点之间的最短距离set minDistance 1e9 ;# 初始值设为一个较大的数# 遍历两组节点的所有组合,计算距离foreach node1 $nodes1 {    foreach node2 $nodes2 {        set dx [expr [lindex $node2 0] - [lindex $node1 0]]        set dy [expr [lindex $node2 1] - [lindex $node1 1]]        set dz [expr [lindex $node2 2] - [lindex $node1 2]]        set distance [expr {sqrt($dx*$dx + $dy*$dy + $dz*$dz)}]        if {$distance < $minDistance} {            set minDistance $distance        }    }}# 输出最短距离puts "最短距离为: $minDistance"

    后面听着电脑风扇呜呜呜的响起,于是,转用Python来重新实现这个任务。同样的数据量不到一秒就计算出来了。

    python的矩阵运算版本

      import numpy as npdef calculate_min_distance(nodes1, nodes2):    matrix1 = np.array(nodes1)    matrix2 = np.array(nodes2)    distance_matrix = np.sqrt(np.sum((matrix1[:, np.newaxis] - matrix2)**2, axis=-1))    min_distance = np.min(distance_matrix)    return min_distance# 示例输入坐标nodes1 = [[2.8095238095238,2.9047619047619 ,0],[2.8095238095238,3, 0.28571428571429] ,[2.8095238095238,30, 0.28571428571429]]nodes2 = [[3 ,2.2380952380952 ,1.047619047619],[3, 2.5238095238095, 0.95238095238095]]# 计算最短距离min_distance = calculate_min_distance(nodes1, nodes2)# 输出最短距离print("最短距离为:", min_distance)

      有一点需要注意,列表之间的格式需要转换一下,tcl列表转换为Python列表代码

        set tcl_list {{1 2 3} {2 3} {2 5 8 9}}set python_list_str ""foreach sublist $tcl_list {    append python_list_str [format "\[%s\]" [join $sublist ","]]    append python_list_str ","}# 去除最后一个逗号set python_list_str [string trimright $python_list_str ","]puts [format "\[%s\]" $python_list_str]

        tcl如何调用python,传送门在这里。

        来源:TodayCAEer
        HyperMesh二次开发pythonUM
        著作权归作者所有,欢迎分享,未经许可,不得转载
        首次发布时间:2024-08-14
        最近编辑:27天前
        TodayCAEer
        本科 签名征集中
        获赞 16粉丝 8文章 163课程 0
        点赞
        收藏
        作者推荐

        深入探索Tcl:从面向过程到面向对象编程

        Tcl(ToolCommandLanguage)是一种解释型的脚本语言,同时也是支持面向对象编程的语言。它提供了多种编程范式,包括面向过程、面向函数、基于命名空间的函数以及面向对象。不过需要注意的是,Tcl中的面向对象编程是基于命名空间和命令的,并没有严格的类和对象的概念。阅读本篇文章,您将了解到:1、tcl语言关于面向对象的语法格式首先,让我们看一段面向过程的Tcl代码:procgreet{name}{puts&quot;Hello,$name!&quot;}setname&quot;Alice&quot;greet$name上述代码定义了一个过程greet,并通过传递参数name实现了输出字符的功能。然后,我们给name赋值为Alice并调用greet过程。接下来是面向函数的Tcl代码:namespaceevalGreeter{variablenameprocset_name{new_name}{set::Greeter::name$new_name}procgreet{}{puts&quot;Hello,$::Greeter::name!&quot;}}Greeter::set_name&quot;Bob&quot;Greeter::greet上述代码使用命名空间(namespace)和变量(variable)来实现了函数式编程。通过命名空间,我们将相关的函数和变量组织在一起。这个例子中,我们使用Greeter命名空间,定义了set_name和greet函数。使用Greeter::set_name函数设置name变量的值,然后调用Greeter::greet函数来输出字符。现在,让我们看一段基于命名空间,共享变量的代码:namespaceevalGreeter{variablenameprocset_name{new_name}{variablenamesetname$new_name}procgreet{}{variablenameputs&quot;Hello,$name!&quot;}}Greeter::set_name&quot;Charlie&quot;Greeter::greet该代码与之前的面向函数的例子类似。不同之处在于,我们使用了variable命令来声明了name变量,这样就可以在所有函数中访问它。最后是基于面向对象的Tcl代码:itcl::classGreeter{privatevariablenameconstructor{new_name}{setname$new_name}methodset_name{new_name}{setname$new_name}methodgreet{}{puts&quot;Hello,$name!&quot;}}setgreeter[Greeternew&quot;Charlie&quot;]$greetergreet在这个示例中,我们使用itcl模块创建了一个名为Greeter的类。类中包含一个私有变量name、一个构造函数以及两个方法set_name和greet。构造函数用于初始化name变量,set_name方法用于设置name的值,greet方法用于输出语句。通过实例化Greeter类,并在构造函数中传递初始名字为&quot;Charlie&quot;,我们创建了一个名为greeter的对象。然后,我们调用对象的&quot;greet&quot;方法,输出&quot;Hello,Charlie!&quot;。接下来就是套话了。面向对象编程的主要优势在于它提供了更好的封装性、模块化和可维护性。通过将相关功能组织在一个类中,我们可以更容易地管理代码,减少代码之间的依赖性,并且可以轻松地创建多个实例,实现更高级的功能。在大型项目中,面向对象的编程范式可以提高代码的可读性和可扩展性。项目规模、团队合作、代码的复用和维护等。但对于二次开发而言代码量不大,使用基于命名空间的函数也是同样适用,通过source函数,同样能实现继承以往代码的效果。不同命名空间重写函数,同样能实现多态的效果。关键是结构还简单,写起来也快。以下是关于HyperMesh面对对象的小案例。packagerequireItclif{[::itcl::findclassNodeOperations]!=&quot;&quot;}{itcl::deleteclassNodeOperations}itcl::classNodeOperations{#定义实例变量variablenodelist#构造函数内容constructor{}{}#设置实例变量methodSelectNode{}{*createmarkpanelnodes1&quot;&quot;setnodelist[hm_getmarknode1]}#使用实例变量nodelist创建中点methodCreateCenter{}{*createmarknodes1{*}$nodelist*createbestcirclecenternodenodes1010}}#使用NodeOperations类创建一个对象setnodeOps[NodeOperations#auto]#调用SelectNode方法,设置实例变量nodelist$nodeOpsSelectNode#调用CreateCenter方法,它会使用实例变量nodelist$nodeOpsCreateCenter来源:TodayCAEer

        未登录
        还没有评论
        课程
        培训
        服务
        行家
        VIP会员 学习 福利任务 兑换礼品
        下载APP
        联系我们
        帮助与反馈