我有一组点,我想传播到由二进制图像定义的形状边界的边缘。形状边界由1px宽的白色边缘定义。
我将这些点的坐标存储在2行×n列矩阵中。该形状形成凹形边界,其内部没有孔,由约2500个点构成。我希望在形状边界上传播大约80到150个点。
我想从正交方向上的点集中的每个点投射光线,并检测它在哪个点与形状边界相交。正交方向已经确定。出于所需目的,使用点-1和点+ 1计算得到的点轮廓法线。
这样做的最佳方法是什么? 是否有可以使用的某种光线跟踪算法?
非常感谢您提前寻求帮助!
编辑:我试图让问题更加清晰,并添加了描述问题的图像。在图像中,灰线表示形状轮廓,红点表示点 我想传播,绿线是一个假想的正射投射光线。alt text http://img504.imageshack.us/img504/3107/orth.png
另一个编辑:为了澄清,我已经发布了用于计算每个点的法线的代码。其中xt和yt是存储每个点的坐标的向量。计算出正常值后,可以使用linspace函数和请求的正交线长度来传播它。
%#derivaties of contour
dx=[xt(2)-xt(1) (xt(3:end)-xt(1:end-2))/2 xt(end)-xt(end-1)];
dy=[yt(2)-yt(1) (yt(3:end)-yt(1:end-2))/2 yt(end)-yt(end-1)];
%#normals of contourpoints
l=sqrt(dx.^2+dy.^2);
nx = -dy./l;
ny = dx./l;
normals = [nx,ny];
答案 0 :(得分:0)
这取决于您要针对一个形状测试多少单位矢量。如果您有一个形状和许多测试,最简单的方法是将您的形状坐标转换为极坐标,这些坐标隐含地代表您的解决方案。这可能不是一个非常有效的解决方案,但是如果你有不同的形状,每种形状只有几个测试。
根据已修改的问题进行更新:
如果光线可以从任意点开始,而不仅是从原点开始,则必须对所有点进行测试。这可以通过变换形状边界来轻松完成,这样您的光线就可以在坐标方向上的原点开始(我的示例代码中为正x)
% vector of shape boundary points (assumed to be image coordinates, i.e. integers)
shapeBoundary = [xs, ys];
% define the start point and direction you want to test
startPoint = [xsp, ysp];
testVector = unit([xv, yv]);
% now transform the shape boundary
shapeBoundaryTrans(:,1) = shapeBoundary(:,1)-startPoint(1);
shapeBoundaryTrans(:,2) = shapeBoundary(:,2)-startPoint(2);
rotMatrix = [testVector(2), testVector(1); ...
testVector(-1), testVector(2)];
% somewhat strange transformation to keep it vectorized
shapeBoundaryTrans = shapeBoundaryTrans * rotMatrix';
% now the test is easy: find the points close to the positive x-axis
selector = (abs(shapeBoundaryTrans(:,2)) < 0.5) & (shapeBoundaryTrans(:,1) > 0);
shapeBoundaryTrans(:,2) = 1:size(shapeBoundaryTrans, 1)';
shapeBoundaryReduced = shapeBoundaryTrans(selector, :);
if (isempty(shapeBoundaryReduced))
[dummy, idx] = min(shapeBoundaryReduced(:, 1));
collIdx = shapeBoundaryReduced(idx, 2);
% you have a collision with point collIdx of your shapeBoundary
else
% no collision
end
这可能会以更好的方式完成,但你明白了......
答案 1 :(得分:0)
如果我正确理解您的问题(将每个点投影到形状边界的最近点),您可以
使用sub2ind
将“2行x列矩阵”描述转换为带有白色像素的BW图像,如
myimage=zeros(imagesize);
myimage(imagesize, x_coords, y_coords) = 1
使用imfill
填充边界的
在生成的图片上运行[D,L] = bwdist(BW)
,然后阅读L
的答案。
应该相当简单。