mattools / matGeom

Matlab geometry toolbox for 2D/3D geometric computing
BSD 2-Clause "Simplified" License
267 stars 98 forks source link

Bugs in intersectEdges.m #157

Closed nuitlejour closed 1 year ago

nuitlejour commented 1 year ago

I am using the lastest matGeom, in source code mmTrace\intersectEdges.m: 79 ` % Process colinear edges

% colinear edges may have 0, 1 or infinite intersection % Discrimnation based on position of edge2 vertices on edge1 if sum(col) > 0 % array for storing results of colinear edges resCol = Inf * ones(size(col));

% compute position of edge2 vertices wrt edge1
t1 = edgePosition(edge2(col, 1:2), edge1(col, :));
t2 = edgePosition(edge2(col, 3:4), edge1(col, :));

% control location of vertices: we want t1<t2
if t1 > t2
    tmp = t1;
    t1  = t2;
    t2  = tmp;
end

% edge totally before first vertex or totally after last vertex
resCol(col(t2 < -tol))  = NaN;
resCol(col(t1 > 1+tol)) = NaN;

% set up result into point coordinate
x0(col) = resCol(col);
y0(col) = resCol(col);

% touches on first point of first edge
touch = col(abs(t2) < tol);
x0(touch) = edge1(touch, 1);
y0(touch) = edge1(touch, 2);

% touches on second point of first edge
touch = col(abs(t1-1) < tol);
x0(touch) = edge1(touch, 3);
y0(touch) = edge1(touch, 4);

end `

It is apparent that t1, t2 should be single-valued, but edgePosition() does not guaranty that.

I made the following change, could you please check and make sure the sementics are correct?

` % Process colinear edges

% colinear edges may have 0, 1 or infinite intersection % Discrimnation based on position of edge2 vertices on edge1 if sum(col) > 0 % array for storing results of colinear edges resCol = Inf * ones(size(col));

% compute position of edge2 vertices wrt edge1
t1 = edgePosition(edge2(col, 1:2), edge1(col, :));
t2 = edgePosition(edge2(col, 3:4), edge1(col, :));

% control location of vertices: we want t1<t2
for ii = 1:size(t1, 1)
    if t1(ii, 1) > t2(ii, 1)
        t1_ii  = t2(ii);
        t2_ii  = t1(ii);
    else
        t1_ii  = t1(ii);
        t2_ii  = t2(ii);
    end

    % edge totally before first vertex or totally after last vertex
    resCol(col(t2_ii < -tol))  = NaN;
    resCol(col(t1_ii > 1+tol)) = NaN;

    % set up result into point coordinate
    x0(col) = resCol(col);
    y0(col) = resCol(col);

    % touches on first point of first edge
    touch = col(abs(t2_ii) < tol);
    x0(touch) = edge1(touch, 1);
    y0(touch) = edge1(touch, 2);

    % touches on second point of first edge
    touch = col(abs(t1_ii-1) < tol);
    x0(touch) = edge1(touch, 3);
    y0(touch) = edge1(touch, 4);

end

end `

dlegland commented 1 year ago

Hi, thanks for reporting! yes, this can be improved. I have started to check, but ran out of time. I'll have another llok next week. Stay tuned...

dlegland commented 1 year ago

Hi, just made a correction in commit a4be53035b5f764df97919a7cffb5dd69f2004d8. Should work better now!