减少Voronoi细胞的区域并确定新顶点的坐标。

4

我已经编写了MATLAB代码,使用Voronoi创建附图。我的兴趣区域是红色圆圈。因此,Voronoi的种子被保留在该区域内。


1
这个计算有点复杂,但是如果你知道每个单元格的每个端点,那么可以循环遍历每对单元格,检查它们共同的端点,然后沿着该端点绘制粗线。想一想,可能更快更简单的方法是沿着每个单元格循环,并用粗线手动绘制单元格边界。你会得到每条边两次,但这不应该是什么大问题。 - Andras Deak -- Слава Україні
@AndrasDeak 谢谢您的评论。我的意图不是增加单元格的宽度,而是减少面积。这样当我将零件导入abaqus软件时,边界可以被视为一个单独的区域,并且可以分配不同的材料属性。我不确定我是否表达清楚。 - rcty
1
如果您能明确在Abaqus中想要做什么,那么建议解决方案会更容易。您是想要部件的装配,还是一个零件,每个Voronoi单元具有不同的属性? - will
@它不会是零件的组装,而是部分的划分。两者之间的区域可以分配不同的材料属性,而不同于晶粒。类似于这个,但更加精细,并且在一个圆形内:http://s24.postimg.org/j3624pr1x/Original.jpg - rcty
1
感谢您添加第二张图片,这样更清晰了。如果cst的答案不够好,请在您的问题中补充说明。如果您只需要执行一次,而且不打算在Python中编写脚本,则可以尝试在草图工具中使用偏移工具。虽然这有点费力,但如果只是一个临时问题,可能已经足够了。 - will
显示剩余2条评论
2个回答

2
想法:一种方法是使用Voronoi单元C{k}关于相应点X(k,:)的同次变换,比例为R,使得0<R<1。单元的形状——角的数量和它们的关联角度——将被保留,并且面积将按比例减少(即通过因子R2而不是一个常数值)。
请注意,这将“破坏”您的单元,因为缩小的Voronoi单元将不再共享顶点/边,因此[V,C]表示不再有效。此外,曾经共同边缘之间的距离将取决于原始单元的面积(更大的单元,相邻边缘之间的距离更大)。
2个二维点的转换示例:
A   = [1,2];        %'Center'
B   = [10,1];       %'To be transformed'
R   = 0.8;          %'Transformation ratio'
trB = A + R*(B-A);  %'Transformed'

谢谢您的回复。听起来非常合适。我可以使用多边形的质心作为中心,并按比例转换每个顶点。让我试一试。谢谢! - rcty
1
我也考虑过这个问题,但是这会使每个单元格缩小一个点。@rcy的版本使用多边形质心解决了这个问题,并使其在视觉上更具吸引力。 - Andras Deak -- Слава Україні
1
@AndrasDeak 没有尝试以图形方式表示,所以我宁愿相信你的话。 :-) 我的想法是至少保留 Voronoi 单元的一个属性,即点到(变换后的)公共边缘的距离相等。 - user2271770

1

我无法理解您对CST-link想法的实现,但这里有一个可行的方案(我在Matlab中测试过,但尚未在Abaqus中测试,生成的代码看起来Abaqus应该可以使用)。

rng(0);
x=rand(40,2);
plot(x(:,1),x(:,2),'x')
[v,c]=voronoin(x);
fact=0.9;

for i=1:length(c)
    cur_cell=c{i};
    coords=v(cur_cell,:);
    if isfinite(coords)
        %fact=somefunctionofarea?;
        centre=x(i,:); % i used the voronoi seeds as my centres
        coords=bsxfun(@minus,coords,centre); %move everything to a local coord sys centred on the seed point
        [theta,rho] = cart2pol(coords(:,1),coords(:,2));
        [xnew, ynew]= pol2cart(theta,rho*fact);
        xnew=xnew+centre(1); % put back in real coords. 
        ynew=ynew+centre(2);
        xnew2=circshift(xnew,1);
        ynew2=circshift(ynew,1);
        fprintf('s1.Line(point1=(%f,%f),point2=(%f,%f))\n',...
            [xnew, ynew, xnew2,ynew2]'); 
        line(xnew,ynew); %testing purposes - doesn't plot last side in matlab
    end
end 

看到这个结果,我认为你需要一种不同的方式来缩小你的边缘。可以减去一个固定面积或者使用其他公式。


非常感谢您的代码,是的,它非常接近我想要的。由于最后一侧没有绘制,abaqus无法将零件勾画出来。我想我会尝试解决这个问题。至少现在我已经接近我的目标了。再次感谢! - rcty
1
@rcy 在Matlab中没有绘制,但在abaqus中绘制。abaqus线条Matlab线条命令不同,因此新的new和new2点是为abaqus而不是Matlab制作的。 - will
现在可以了!是我的错!我打错了一个字母。非常感谢你的帮助! - rcty

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接