明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 728|回复: 4

随机缩放、旋转和移动(有更强大的,这个免费)

[复制链接]
发表于 2025-11-15 21:10:12 | 显示全部楼层 |阅读模式
本帖最后由 小毛草 于 2025-12-11 09:33 编辑
  1. ;;;;;;;;;;;;;;;;;;;;;随机缩放、旋转和移动(各自中心点,带记忆功能,面板设置);;;;;;;;;;;;;;;;;;;;;;;;;;

  2. ;; 全局变量用于记忆上次使用的参数
  3. (setq *rrs_last_min_scale* 0.5)
  4. (setq *rrs_last_max_scale* 2.0)
  5. (setq *rrs_last_min_angle* 0.0)
  6. (setq *rrs_last_max_angle* 0.0)
  7. (setq *rrs_last_min_move* 0.0)
  8. (setq *rrs_last_max_move* 0.0)

  9. (defun c:rrs (/ *error* old_cmd ss min_scale max_scale min_angle max_angle min_move max_move
  10.                 ent i scale_factor angle move_x move_y center_pt seed user_input params)
  11.   
  12.   ;; 错误处理函数
  13.   (defun *error* (msg)
  14.     (if (not (wcmatch (strcase msg) "*BREAK*,*CANCEL*,*EXIT*"))
  15.       (princ (strcat "\n错误: " msg))
  16.     )
  17.     (setvar "CMDECHO" old_cmd)
  18.     (princ)
  19.   )
  20.   
  21.   ;; 保存系统变量
  22.   (setq old_cmd (getvar "CMDECHO"))
  23.   (setvar "CMDECHO" 0)
  24.   
  25.   ;; 选择对象
  26.   (princ "\n选择要缩放、旋转和移动的对象: ")
  27.   (setq ss (ssget))
  28.   
  29.   (if ss
  30.     (progn
  31.       ;; 显示当前参数并询问是否需要设置新参数
  32.       (princ (strcat "\n当前参数: 缩放 " (rtos *rrs_last_min_scale* 2 2) " 到 " (rtos *rrs_last_max_scale* 2 2)
  33.                      ", 旋转 " (rtos *rrs_last_min_angle* 2 2) " 到 " (rtos *rrs_last_max_angle* 2 2) "°"
  34.                      ", 移动 " (rtos *rrs_last_min_move* 2 2) " 到 " (rtos *rrs_last_max_move* 2 2)))
  35.       (initget "S s")
  36.       (setq user_input (getkword "\n按[S]设置参数/<直接执行>: "))
  37.       
  38.       (if (or (equal user_input "S") (equal user_input "s"))
  39.         (progn
  40.           ;; 调用面板设置参数
  41.           (if (setq params (show_settings_panel))
  42.             (progn
  43.               (setq min_scale (nth 0 params)
  44.                     max_scale (nth 1 params)
  45.                     min_angle (nth 2 params)
  46.                     max_angle (nth 3 params)
  47.                     min_move (nth 4 params)
  48.                     max_move (nth 5 params))
  49.               
  50.               ;; 更新记忆值
  51.               (setq *rrs_last_min_scale* min_scale
  52.                     *rrs_last_max_scale* max_scale
  53.                     *rrs_last_min_angle* min_angle
  54.                     *rrs_last_max_angle* max_angle
  55.                     *rrs_last_min_move* min_move
  56.                     *rrs_last_max_move* max_move)
  57.                     
  58.               (princ (strcat "\n使用新参数: 缩放 " (rtos min_scale 2 2) " 到 " (rtos max_scale 2 2)
  59.                            ", 旋转 " (rtos min_angle 2 2) " 到 " (rtos max_angle 2 2) "°"
  60.                            ", 移动 " (rtos min_move 2 2) " 到 " (rtos max_move 2 2)))
  61.             )
  62.             (progn
  63.               (princ "\n用户取消设置,使用记忆参数。")
  64.               (setq min_scale *rrs_last_min_scale*
  65.                     max_scale *rrs_last_max_scale*
  66.                     min_angle *rrs_last_min_angle*
  67.                     max_angle *rrs_last_max_angle*
  68.                     min_move *rrs_last_min_move*
  69.                     max_move *rrs_last_max_move*)
  70.             )
  71.           )
  72.         )
  73.         (progn
  74.           ;; 使用记忆的参数
  75.           (setq min_scale *rrs_last_min_scale*
  76.                 max_scale *rrs_last_max_scale*
  77.                 min_angle *rrs_last_min_angle*
  78.                 max_angle *rrs_last_max_angle*
  79.                 min_move *rrs_last_min_move*
  80.                 max_move *rrs_last_max_move*)
  81.           (princ "\n使用记忆参数执行...")
  82.         )
  83.       )
  84.       
  85.       ;; 验证参数范围
  86.       (if (or (<= max_scale min_scale)
  87.               (and (/= min_angle max_angle) (< max_angle min_angle))
  88.               (and (/= min_move max_move) (< max_move min_move)))
  89.         (progn
  90.           (princ "\n错误: 参数范围设置不正确!")
  91.           (setvar "CMDECHO" old_cmd)
  92.           (princ)
  93.         )
  94.       )
  95.       
  96.       ;; 初始化随机种子
  97.       (setq seed (getvar "MILLISECS"))
  98.       
  99.       ;; 遍历选择集并缩放、旋转和移动每个对象
  100.       (setq i 0)
  101.       (repeat (sslength ss)
  102.         (setq ent (ssname ss i))
  103.         
  104.         ;; 获取对象的中心点
  105.         (setq center_pt (get_entity_center ent))
  106.         
  107.         (if center_pt
  108.           (progn
  109.             ;; 为每个对象生成独立的随机缩放比例
  110.             (setq scale_factor (better_random min_scale max_scale seed i))
  111.             
  112.             ;; 执行缩放命令,以对象中心点为基点
  113.             (command "_.scale" ent "" "_non" center_pt scale_factor)
  114.             
  115.             ;; 如果设置了旋转角度范围,则进行随机旋转
  116.             (if (/= min_angle max_angle)
  117.               (progn
  118.                 ;; 为每个对象生成独立的随机旋转角度
  119.                 (setq angle (better_random min_angle max_angle seed (+ i 1000)))
  120.                
  121.                 ;; 执行旋转命令,以对象中心点为基点
  122.                 (command "_.rotate" ent "" "_non" center_pt angle)
  123.               )
  124.             )
  125.             
  126.             ;; 如果设置了移动距离范围,则进行随机移动
  127.             (if (/= min_move max_move)
  128.               (progn
  129.                 ;; 为每个对象生成独立的随机移动向量
  130.                 (setq move_x (better_random (- max_move) max_move seed (+ i 2000)))
  131.                 (setq move_y (better_random (- max_move) max_move seed (+ i 3000)))
  132.                
  133.                 ;; 执行移动命令
  134.                 (command "_.move" ent "" "_non" center_pt
  135.                          "_non" (list (+ (car center_pt) move_x)
  136.                                       (+ (cadr center_pt) move_y)
  137.                                       (caddr center_pt)))
  138.               )
  139.             )
  140.             
  141.             ;; 输出处理结果
  142.             (princ (strcat "\n对象 " (itoa (1+ i)) " 缩放比例: " (rtos scale_factor 2 3)))
  143.             (if (/= min_angle max_angle)
  144.               (princ (strcat ", 旋转角度: " (rtos angle 2 2) "°"))
  145.             )
  146.             (if (/= min_move max_move)
  147.               (princ (strcat ", 移动距离: " (rtos (sqrt (+ (* move_x move_x) (* move_y move_y))) 2 2)))
  148.             )
  149.           )
  150.           (princ (strcat "\n警告: 无法获取对象 " (itoa (1+ i)) " 的中心点,跳过处理"))
  151.         )
  152.         
  153.         (setq i (1+ i))
  154.       )
  155.       
  156.       (princ (strcat "\n成功处理 " (itoa i) " 个对象"))
  157.       (princ (strcat "\n缩放比例范围: " (rtos min_scale 2 2) " 到 " (rtos max_scale 2 2)))
  158.       (if (/= min_angle max_angle)
  159.         (princ (strcat "\n旋转角度范围: " (rtos min_angle 2 2) " 到 " (rtos max_angle 2 2) "°"))
  160.       )
  161.       (if (/= min_move max_move)
  162.         (princ (strcat "\n移动距离范围: " (rtos min_move 2 2) " 到 " (rtos max_move 2 2)))
  163.       )
  164.     )
  165.     (princ "\n未选择任何对象。")
  166.   )
  167.   
  168.   ;; 恢复系统变量
  169.   (setvar "CMDECHO" old_cmd)
  170.   (princ)
  171. )

  172. ;; 显示设置面板函数
  173. (defun show_settings_panel (/ dcl_id dcl_file dcl_name result params validation_result)
  174.   ;; 创建DCL文件内容
  175.   (setq dcl_file (vl-filename-mktemp "rrs_settings.dcl")
  176.         dcl_name "rrs_settings")
  177.   
  178.   ;; 写入DCL内容到临时文件
  179.   (if (not (write_dcl_file dcl_file))
  180.     (progn
  181.       (princ "\n无法创建对话框文件!")
  182.       (return nil)
  183.     )
  184.   )
  185.   
  186.   ;; 加载对话框
  187.   (setq dcl_id (load_dialog dcl_file))
  188.   
  189.   (if (not (new_dialog dcl_name dcl_id))
  190.     (progn
  191.       (princ "\n无法加载设置对话框!")
  192.       (unload_dialog dcl_id)
  193.       (vl-file-delete dcl_file)
  194.       (return nil)
  195.     )
  196.   )
  197.   
  198.   ;; 设置初始值
  199.   (set_tile "min_scale" (rtos *rrs_last_min_scale* 2 2))
  200.   (set_tile "max_scale" (rtos *rrs_last_max_scale* 2 2))
  201.   (set_tile "min_angle" (rtos *rrs_last_min_angle* 2 2))
  202.   (set_tile "max_angle" (rtos *rrs_last_max_angle* 2 2))
  203.   (set_tile "min_move" (rtos *rrs_last_min_move* 2 2))
  204.   (set_tile "max_move" (rtos *rrs_last_max_move* 2 2))
  205.   
  206.   ;; 确定按钮动作
  207.   (action_tile "accept"
  208.     "(setq params (get_dialog_values))
  209.      (setq validation_result (validate_dialog_values params))
  210.      (if validation_result
  211.        (done_dialog 1)
  212.        (progn
  213.          (alert "参数值无效,请检查输入!")
  214.        )
  215.      )")
  216.   
  217.   ;; 取消按钮动作
  218.   (action_tile "cancel" "(done_dialog 0)")
  219.   
  220.   ;; 重置按钮动作 - 重置为默认值
  221.   (action_tile "reset"
  222.     "(set_tile "min_scale" "0.5")
  223.      (set_tile "max_scale" "2.0")
  224.      (set_tile "min_angle" "0.0")
  225.      (set_tile "max_angle" "0.0")
  226.      (set_tile "min_move" "0.0")
  227.      (set_tile "max_move" "0.0")")
  228.   
  229.   ;; 显示对话框并等待用户响应
  230.   (setq result (start_dialog))
  231.   (unload_dialog dcl_id)
  232.   (vl-file-delete dcl_file)
  233.   
  234.   ;; 处理结果
  235.   (if (and (= result 1) params validation_result)
  236.     params
  237.     nil
  238.   )
  239. )

  240. ;; 验证对话框值的函数
  241. (defun validate_dialog_values (params / min_scale max_scale min_angle max_angle min_move max_move)
  242.   (if (not params)
  243.     (return nil)
  244.   )
  245.   
  246.   (setq min_scale (nth 0 params)
  247.         max_scale (nth 1 params)
  248.         min_angle (nth 2 params)
  249.         max_angle (nth 3 params)
  250.         min_move (nth 4 params)
  251.         max_move (nth 5 params))
  252.   
  253.   ;; 检查是否为有效数字
  254.   (if (or (not (numberp min_scale)) (not (numberp max_scale))
  255.           (not (numberp min_angle)) (not (numberp max_angle))
  256.           (not (numberp min_move)) (not (numberp max_move)))
  257.     (progn
  258.       (princ "\n错误: 参数必须为数字!")
  259.       (return nil)
  260.     )
  261.   )
  262.   
  263.   ;; 检查范围
  264.   (cond
  265.     ((<= max_scale min_scale)
  266.      (princ "\n错误: 最大缩放比例必须大于最小缩放比例!")
  267.      nil
  268.     )
  269.     ((and (/= min_angle max_angle) (< max_angle min_angle))
  270.      (princ "\n错误: 最大旋转角度必须大于最小旋转角度!")
  271.      nil
  272.     )
  273.     ((and (/= min_move max_move) (< max_move min_move))
  274.      (princ "\n错误: 最大移动距离必须大于最小移动距离!")
  275.      nil
  276.     )
  277.     (t t)
  278.   )
  279. )

  280. ;; 获取对话框值的函数
  281. (defun get_dialog_values (/ min_scale max_scale min_angle max_angle min_move max_move
  282.                            str_min_scale str_max_scale str_min_angle str_max_angle str_min_move str_max_move)
  283.   (setq str_min_scale (get_tile "min_scale")
  284.         str_max_scale (get_tile "max_scale")
  285.         str_min_angle (get_tile "min_angle")
  286.         str_max_angle (get_tile "max_angle")
  287.         str_min_move (get_tile "min_move")
  288.         str_max_move (get_tile "max_move"))
  289.   
  290.   ;; 确保所有值都是有效的数字,如果为空则使用记忆值
  291.   (setq min_scale (if (and str_min_scale (/= str_min_scale ""))
  292.                     (atof str_min_scale)
  293.                     *rrs_last_min_scale*))
  294.                     
  295.   (setq max_scale (if (and str_max_scale (/= str_max_scale ""))
  296.                     (atof str_max_scale)
  297.                     *rrs_last_max_scale*))
  298.                     
  299.   (setq min_angle (if (and str_min_angle (/= str_min_angle ""))
  300.                     (atof str_min_angle)
  301.                     *rrs_last_min_angle*))
  302.                     
  303.   (setq max_angle (if (and str_max_angle (/= str_max_angle ""))
  304.                     (atof str_max_angle)
  305.                     *rrs_last_max_angle*))
  306.                     
  307.   (setq min_move (if (and str_min_move (/= str_min_move ""))
  308.                    (atof str_min_move)
  309.                    *rrs_last_min_move*))
  310.                   
  311.   (setq max_move (if (and str_max_move (/= str_max_move ""))
  312.                    (atof str_max_move)
  313.                    *rrs_last_max_move*))
  314.   
  315.   (list min_scale max_scale min_angle max_angle min_move max_move)
  316. )

  317. ;; 写入DCL文件函数
  318. (defun write_dcl_file (filename)
  319.   (setq dcl_content (strcat
  320.     "rrs_settings : dialog {\n"
  321.     "  label = "随机缩放旋转设置";\n"
  322.     "  : boxed_column {\n"
  323.     "    label = "缩放设置";\n"
  324.     "    : row {\n"
  325.     "      : text { label = "最小比例:"; width = 10; }\n"
  326.     "      : edit_box { key = "min_scale"; width = 10; fixed_width = true; }\n"
  327.     "    }\n"
  328.     "    : row {\n"
  329.     "      : text { label = "最大比例:"; width = 10; }\n"
  330.     "      : edit_box { key = "max_scale"; width = 10; fixed_width = true; }\n"
  331.     "    }\n"
  332.     "  }\n"
  333.     "  : boxed_column {\n"
  334.     "    label = "旋转设置";\n"
  335.     "    : row {\n"
  336.     "      : text { label = "最小角度:"; width = 10; }\n"
  337.     "      : edit_box { key = "min_angle"; width = 10; fixed_width = true; }\n"
  338.     "    }\n"
  339.     "    : row {\n"
  340.     "      : text { label = "最大角度:"; width = 10; }\n"
  341.     "      : edit_box { key = "max_angle"; width = 10; fixed_width = true; }\n"
  342.     "    }\n"
  343.     "  }\n"
  344.     "  : boxed_column {\n"
  345.     "    label = "移动设置";\n"
  346.     "    : row {\n"
  347.     "      : text { label = "最小距离:"; width = 10; }\n"
  348.     "      : edit_box { key = "min_move"; width = 10; fixed_width = true; }\n"
  349.     "    }\n"
  350.     "    : row {\n"
  351.     "      : text { label = "最大距离:"; width = 10; }\n"
  352.     "      : edit_box { key = "max_move"; width = 10; fixed_width = true; }\n"
  353.     "    }\n"
  354.     "  }\n"
  355.     "  spacer;\n"
  356.     "  : row {\n"
  357.     "    : button { key = "reset"; label = "重置默认"; width = 12; fixed_width = true; }\n"
  358.     "    : spacer { width = 2; }\n"
  359.     "    : button { key = "cancel"; label = "取消"; width = 8; fixed_width = true; is_cancel = true; }\n"
  360.     "    : button { key = "accept"; label = "确定"; width = 8; fixed_width = true; is_default = true; }\n"
  361.     "  }\n"
  362.     "}\n"
  363.   ))
  364.   
  365.   (if (setq fp (open filename "w"))
  366.     (progn
  367.       (write-line dcl_content fp)
  368.       (close fp)
  369.       T
  370.     )
  371.     nil
  372.   )
  373. )

  374. ;; 获取对象中心点函数
  375. (defun get_entity_center (ent / obj minpt maxpt center)
  376.   (if (and ent (entget ent))
  377.     (progn
  378.       (setq obj (vlax-ename->vla-object ent))
  379.       (if obj
  380.         (progn
  381.           (vla-getboundingbox obj 'minpt 'maxpt)
  382.           (setq minpt (vlax-safearray->list minpt)
  383.                 maxpt (vlax-safearray->list maxpt))
  384.           (setq center (list
  385.                          (/ (+ (car minpt) (car maxpt)) 2.0)
  386.                          (/ (+ (cadr minpt) (cadr maxpt)) 2.0)
  387.                          (/ (+ (caddr minpt) (caddr maxpt)) 2.0)
  388.                        ))
  389.           center
  390.         )
  391.         nil
  392.       )
  393.     )
  394.     nil
  395.   )
  396. )

  397. ;; 改进的随机数生成函数
  398. (defun better_random (min_val max_val seed index / x)
  399.   (setq x (* (getvar "MILLISECS") (1+ index) seed (getvar "CDATE")))
  400.   (setq x (rem x 1000000))
  401.   (setq x (rem (+ x (* index 7919)) 1000000))
  402.   (setq x (/ (float x) 1000000.0))
  403.   
  404.   (+ min_val (* x (- max_val min_val)))
  405. )

  406. (princ "\n随机缩放旋转移动命令已加载,输入 RRS 使用。")
  407. (princ)

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

x
回复

使用道具 举报

发表于 2025-11-16 01:30:22 | 显示全部楼层
迷失1786 发表于 2025-11-15 21:35
起码来个图吧,现在AI都那么懒了?

都这么简单了还索要币,那说明什么问题。
回复 支持 1 反对 0

使用道具 举报

发表于 2025-11-15 21:35:56 | 显示全部楼层
起码来个图吧,现在AI都那么懒了?

点评

看文字 就明白了,这么简单还要配什么图!  发表于 2025-11-15 22:02
回复 支持 反对

使用道具 举报

发表于 3 天前 | 显示全部楼层
画图谁要随机缩放的?你是来搞笑的吧
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2026-1-2 05:15 , Processed in 0.169142 second(s), 26 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表