TikZ生成随机点并连接间距小于4cm点的实现方法
TikZ随机点按距离阈值连线实现方案
核心问题分析
原有代码在生成每个随机点的同时直接绘制到原点的连线,没有留存点坐标做后续两两判断;如果直接嵌套循环重跑随机数生成逻辑,会导致随机数种子偏移,最终绘制的点位置和连线目标完全不匹配。
实现逻辑
- 固定随机种子后,第一轮循环仅负责生成10个随机点,将每个点的x、y坐标存入全局可访问的索引宏中,同步绘制红色散点,这一步不做任何连线操作
- 第二轮采用双层循环遍历所有不重复的点对(j从i+1开始,避免重复连线),计算两点欧氏距离,仅当距离小于4cm时绘制蓝色密虚线
- 全程仅执行一次随机数生成序列,从根源上避免随机种子错位问题
完整代码
\documentclass{standalone} \usepackage{tikz} \begin{document} \begin{tikzpicture} % 绘制背景网格 \draw[step=0.5cm,color=gray] (-2.5,-2.5) grid (2.5,2.5); \pgfmathsetseed{2} % 固定随机种子,保证点位置和原代码完全一致 % 第一步:生成所有随机点,存储坐标并绘制红点 \foreach \i in {1,...,10}{ \pgfmathrandominteger{\a}{-240}{240} \pgfmathrandominteger{\b}{-240}{240} % 定义全局宏存储第i个点的坐标,跨foreach分组可访问 \expandafter\xdef\csname pointx\i\endcsname{\fpeval{\a*0.01}} \expandafter\xdef\csname pointy\i\endcsname{\fpeval{\b*0.01}} % 绘制红色散点 \fill [color=red] (\a*0.01,\b*0.01) circle (0.1); } % 第二步:遍历点对,满足距离阈值则连线 \foreach \i in {1,...,9}{ \foreach \j in {\the\numexpr\i+1,...,10}{ % 读取对应点坐标 \pgfmathsetmacro\xi{\csname pointx\i\endcsname} \pgfmathsetmacro\yi{\csname pointy\i\endcsname} \pgfmathsetmacro\xj{\csname pointx\j\endcsname} \pgfmathsetmacro\yj{\csname pointy\j\endcsname} % 计算两点欧氏距离 \pgfmathsetmacro\dist{sqrt((\xi-\xj)^2 + (\yi-\yj)^2)} % 距离小于4cm时绘制蓝色密虚线 \ifdim\dist cm <4cm \draw [color=blue,densely dotted] (\xi,\yi) -- (\xj,\yj); \fi } } \end{tikzpicture} \end{document}
关键细节说明
- 坐标存储使用
\expandafter\xdef\csname \endcsname定义全局索引宏,解决TikZ/TeX中\foreach分组内变量无法被外层循环访问的问题 - 双层循环遍历点对时,j的起始值设为i+1,不会重复绘制同一对点的双向连线,减少冗余绘制操作
- 距离判断使用TeX原生的
\ifdim尺寸比较语法,执行效率高于纯浮点运算比较 - 由于随机种子和随机数生成逻辑和原代码完全一致,生成的10个红色点位置和原代码输出完全相同,不会出现点位偏移
修改前原代码效果参考:
内容的提问来源于stack exchange,提问作者dcat52
相关产品推荐
相关产品推荐

