matlab对线段和圆进行检测,Matlab – 检测线段和圆之间碰撞的功能失败

已经存在许多问题,涉及如何检测线段和圆之间的碰撞.

在我的代码中,我使用Matlab的linecirc函数,然后将它返回的交点与我的线段的末端进行比较,以检查这些点是否在线内(linecirc假定无限线,我没有/想要).

将一些sprintf调用复制并添加到linecirc函数会显示它正在按预期计算点.这些似乎被我的功能所迷失.

我的代码如下:

function cutCount = getCutCountHex(R_g, centre)

clf;

cutCount = 0;

% Generate a hex grid

Dg = R_g*2;

L_b = 62;

range = L_b*8;

dx = Dg*cosd(30);

dy = 3*R_g;

xMax = ceil(range/dx); yMax = ceil(range/dy);

d1 = @(xc, yc) [dx*xc dy*yc];

d2 = @(xc, yc) [dx*(xc+0.5) dy*(yc+0.5)];

centres = zeros((xMax*yMax),2);

count = 1;

for yc = 0:yMax-1

for xc = 0:xMax-1

centres(count,:) = d1(xc, yc);

count = count + 1;

centres(count, :) = d2(xc, yc);

count = count + 1;

end

end

for i=1:size(centres,1)

centres(i,:) = centres(i,:) - [xMax/2 * dx, yMax/2 * dy];

end

hold on

axis equal

% Get counter for intersected lines

[VertexX, VertexY] = voronoi(centres(:,1), centres(:,2));

numLines = size(VertexX, 2);

for lc = 1:numLines

segStartPt = [VertexX(1,lc) VertexY(1,lc)];

segEndPt = [VertexX(2,lc) VertexY(2,lc)];

slope = (segEndPt(2) - segStartPt(2))/(segEndPt(1) - segStartPt(1));

intercept = segEndPt(2) - (slope*segEndPt(1));

testSlope = isinf(slope);

if (testSlope(1)==1)

% Pass the x-axis intercept instead

intercept = segStartPt(1);

end

[xInterceptionPoints, yInterceptionPoints] = ...

linecirc(slope, intercept, centre(1), centre(2), L_b);

testArr = isnan(xInterceptionPoints);

if (testArr(1) == 0) % Line intersects. Line segment may not.

interceptionPoint1 = [xInterceptionPoints(1), yInterceptionPoints(1)];

interceptionPoint2 = [xInterceptionPoints(2), yInterceptionPoints(2)];

% Test if first intersection is on the line segment

p1OnSeg = onSeg(segStartPt, segEndPt, interceptionPoint1);

p2OnSeg = onSeg(segStartPt, segEndPt, interceptionPoint2);

if (p1OnSeg == 1)

cutCount = cutCount + 1;

scatter(interceptionPoint1(1), interceptionPoint1(2), 60, 'MarkerFaceColor', 'r', 'MarkerEdgeColor', 'k');

end

% Test if second intersection point is on the line segment

if (interceptionPoint1(1) ~= interceptionPoint2(1) || interceptionPoint1(2) ~= interceptionPoint2(2)) % Don't double count touching points

if (p2OnSeg == 1)

cutCount = cutCount + 1;

scatter(interceptionPoint2(1), interceptionPoint2(2), 60, 'MarkerFaceColor', 'r', 'MarkerEdgeColor', 'k');

end

end

end

end

% Plot circle

viscircles(centre, L_b, 'EdgeColor', 'b');

H = voronoi(centres(:,1), centres(:,2));

for i = 1:size(H)

set(H(i), 'Color', 'g');

end

end

function boolVal = onSeg(segStart, segEnd, testPoint)

bvX = isBetweenOrEq(segStart(1), segEnd(1), testPoint(1));

bvY = isBetweenOrEq(segStart(2), segEnd(2), testPoint(2));

if (bvX == 1 && bvY == 1)

boolVal = 1;

else

boolVal = 0;

end

end

function boolVal = isBetweenOrEq(end1, end2, test)

if ((test <= end1 && test >= end2) || (test >= end1 && test <= end2))

boolVal = 1;

else

boolVal = 0;

end

end

它创建一个六边形网格,然后计算以固定半径(在本例中为62)和指定中心绘制的圆之间的交叉数.

分散调用显示函数计数的位置.

在if(p1OnSeg == 1)块中实现sprintf调用表明我的函数选择了虚拟交叉点(尽管它然后正确处理它们)

if (interceptionPoint1(1) > -26 && interceptionPoint1(1) < -25)

sprintf('p1 = [%f, %f]. Vx = [%f, %f], Vy = [%f, %f].\nxint = [%f, %f], yint = [%f, %f]',...

interceptionPoint1(1), interceptionPoint1(2), VertexX(1,lc), VertexX(2,lc), VertexY(1,lc), VertexY(2,lc),...

xInterceptionPoints(1), xInterceptionPoints(2), yInterceptionPoints(1), yInterceptionPoints(2))

end

输出

p1 = [-25.980762, 0.000000]. Vx = [-25.980762, -25.980762], Vy = [-15.000000, 15.000000].

xint = [-25.980762, -25.980762], yint = [0.000000, 0.000000]

一张图片显示了奇怪的一点.

很抱歉很长的问题但是 – 为什么会被检测到.它们不位于圆上(在mylinecirc函数中显示值会检测大约(-25,55)和(-25,-55)左右的交点(如无限线所期望的那样).

移动圆圈可以删除这些点,但有时这会导致其他检测问题.这是怎么回事?

编辑:旋转由[Vx,Vy] = voronoi(…)创建的网格图案,然后删除具有非常大值的点(即接近无穷大的点等)似乎已解决此问题.为了避免NaN值出现在“斜率”和“截距”中,似乎必须删除“大”值点.我的猜测是这与旋转引起的轻微倾斜有关,再加上预期截距的溢出.

添加的示例代码如下.我还在Jan de Gier的代码中进行了编辑,但这对问题没有任何影响,因此在问题代码中没有改变.

%Rotate slightly

RotAngle = 8;

RotMat = [cosd(RotAngle), -sind(RotAngle); sind(RotAngle), cosd(RotAngle)];

for i=1:size(centres,1)

centres(i,:) = centres(i,:) - [floor(xMax/2) * dx, floor(yMax/2) * dy]; %Translation

centres(i,:) = ( RotMat * centres(i,:)' ); %Rotation

end

% Get counter for intersected lines

[VertexX, VertexY] = voronoi(centres(:,1), centres(:,2));

% Filter vertices

numLines = size(VertexX, 2);

newVx = [];

newVy = [];

for lc = 1:numLines

testVec = [VertexX(:,lc) VertexY(:,lc)];

if ~any(abs(testVec) > range*1.5)

newVx = [newVx; VertexX(:,lc)'];

newVy = [newVy; VertexY(:,lc)'];

end

end

VertexX = newVx';

VertexY = newVy';

numLines = size(VertexX, 2);

仍然欣赏答案或建议,以澄清为什么会发生这种情况.

导致这种情况的示例值是getCutCountHex(30,[0,0])和…(35,[0,0])

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值