You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VR地图最短路径分段边界框绘制异常的修复方案咨询

问题:VR地图最短路径分段边界框绘制异常修复

需求说明

在虚拟现实(VR)地图的最短路径中,我们需要按转弯分段主路径,以此根据用户导航轨迹(图中蓝线)在最短路径上的行走距离进行打分。

当前问题

当前算法可正常绘制第一段路径的边界框,但后续路径段的边界框尺寸与第一段完全相同,且紧邻第一段的x、y线段位置(对应idealPath变量)。
第一段路径分段正常
第二段路径分段异常

诉求

如何修复现有代码,实现正确检测后续路径段并绘制对应的橙色分段边界框?其中idealPath为94666×2的矩阵,第一列为x坐标,第二列为y坐标,构成图中绿色的最短路径。

当前代码

function plotSegmentedCheckpoints(trajectory_raw, idealPath, checkpointInfo)
    % Clear and hold the plot
    cla;
    hold on;
    
    % Plot ideal path in green
    plot(idealPath(:,1), idealPath(:,2), 'g.', 'MarkerSize', 5, 'DisplayName', 'Ideal Path');
    
    % Plot trajectory in blue
    scatter(trajectory_raw(:,1), trajectory_raw(:,2), 15, 'b', 'filled', 'DisplayName', 'Trajectory');

    % Get path segments
    [segmentIndices, numSegments] = findPathSegments(idealPath);
    
    % Initialize checkpoint storage
    checkpoint_bounds = zeros(numSegments, 4);  % [x1, x2, y1, y2]
    reached = false(numSegments, 1);
    
    % Constants
    BOX_WIDTH = 86;  % Width of checkpoint boxes
    
    % Process each segment
    for i = 1:numSegments
        % Get current segment
        startIdx = segmentIndices(i);
        endIdx = segmentIndices(i+1);
        segmentPoints = idealPath(startIdx:endIdx, :);
        
        % Calculate segment bounds
        [bounds, orientation] = calculateSegmentBounds(segmentPoints, BOX_WIDTH);
        checkpoint_bounds(i,:) = bounds;
        
        % Check if trajectory reaches this checkpoint
        reached(i) = checkCheckpointReached(trajectory_raw, bounds);
        
        % Draw checkpoint box
        drawCheckpointBox(bounds, reached(i), i);
        
        % Draw direction arrow to next checkpoint if not last segment
        if i < numSegments
            drawDirectionArrow(bounds, idealPath(segmentIndices(i+1),:));
        end
    end
    
    % Calculate and display score
    score = calculateScore(reached, numSegments);
    
    % Configure plot
    configureplot();
    
    % Update title with progress
    title(sprintf('Checkpoint Progress: (%d/%d)\nScore: %.2f', ...
          sum(reached), numSegments, score));
    
    % Store checkpoint information
    checkpointInfo.bounds = checkpoint_bounds;
    checkpointInfo.reached = reached;
    checkpointInfo.score = score;
end

% Function to find path segments based on direction changes
function [segmentIndices, numSegments] = findPathSegments(idealPath)
    % Calculate path directions
    vectors = diff(idealPath);
    angles = atan2(vectors(:,2), vectors(:,1));
    
    % Find significant direction changes (> 30 degrees)
    angleChanges = [true; abs(diff(angles)) > pi/6];
    
    % Combine consecutive changes that are very close
    MIN_SEGMENT_LENGTH = 50;
    for i = 2:length(angleChanges)-1
        if angleChanges(i) && angleChanges(i+1) && ...
           (i - find(angleChanges(1:i-1), 1, 'last') < MIN_SEGMENT_LENGTH)
            angleChanges(i) = false;
        end
    end
    
    % Get indices where direction changes significantly
    segmentIndices = find(angleChanges);
    
    % Ensure first and last points are included
    if segmentIndices(1) ~= 1
        segmentIndices = [1; segmentIndices];
    end
    if segmentIndices(end) ~= size(idealPath,1)
        segmentIndices = [segmentIndices; size(idealPath,1)];
    end
    
    % Number of segments
    numSegments = length(segmentIndices) - 1;
end

% Function to calculate bounds for a segment
function [bounds, orientation] = calculateSegmentBounds(segmentPoints, BOX_WIDTH)
    % Determine if segment is more vertical or horizontal
    endpoint_diff = diff(segmentPoints([1 end],:));
    is_vertical = abs(endpoint_diff(2)) > abs(endpoint_diff(1));
    
    if is_vertical
        % Vertical segment
        x_center = mean(segmentPoints(:,1));
        y_range = [min(segmentPoints(:,2)), max(segmentPoints(:,2))];
        
        bounds = [
            x_center ,  % x1
            x_center + BOX_WIDTH,  % x2
            y_range(1),              % y1
            y_range(2)               % y2
        ];
        orientation = 'vertical';
    else
        % Horizontal segment
        y_center = mean(segmentPoints(:,2));
        x_range = [min(segmentPoints(:,1)), max(segmentPoints(:,1))];
        
        bounds = [
            x_range(1),              % x1
            x_range(2),              % x2
            y_center ,  % y1
            y_center + BOX_WIDTH   % y2
        ];
        orientation = 'horizontal';
    end
end

% Function to check if trajectory reaches checkpoint
function reached = checkCheckpointReached(trajectory, bounds)
    in_x = trajectory(:,1) >= bounds(1) && trajectory(:,1) <= bounds(2);
    in_y = trajectory(:,2) >= bounds(3) && trajectory(:,2) <= bounds(4);
    reached = any(in_x && in_y);
end

% Function to draw checkpoint box
function drawCheckpointBox(bounds, is_reached, checkpoint_number)
    x = [bounds(1), bounds(2), bounds(2), bounds(1), bounds(1)];
    y = [bounds(3), bounds(3), bounds(4), bounds(4), bounds(3)];
    
    if is_reached
        fill(x(1:4), y(1:4), [0.8 1 0.8], 'FaceAlpha', 0.3, 'EdgeColor', 'k', 'LineWidth', 1);
    else
        fill(x(1:4), y(1:4), [1 0.8 0.8], 'FaceAlpha', 0.3, 'EdgeColor', 'k', 'LineWidth', 1);
    end
    
    % Add checkpoint number
    text(mean([bounds(1), bounds(2)]), mean([bounds(3), bounds(4)]), ...
         num2str(checkpoint_number), 'HorizontalAlignment', 'center', ...
         'VerticalAlignment', 'middle', 'FontSize', 12, ...
         'FontWeight', 'bold', 'Color', 'k');
end

% Function to draw direction arrow
function drawDirectionArrow(current_bounds, next_point)
    % Calculate arrow start point (center of current box)
    arrow_start = [
        mean([current_bounds(1), current_bounds(2)]), 
        mean([current_bounds(3), current_bounds(4)])
    ];
    
    % Calculate direction to next checkpoint
    dir_vec = next_point - arrow_start;
    dir_vec = dir_vec / norm(dir_vec) * 50;  % Fixed length arrows
    
    % Draw arrow
    quiver(arrow_start(1), arrow_start(2), dir_vec(1), dir_vec(2), 0, ...
           'Color', [1 0.5 0], 'LineWidth', 2, 'MaxHeadSize', 0.5);
end

% Function to calculate score
function score = calculateScore(reached, numSegments)
    weights = linspace(1, 2, numSegments);
    score = sum(reached .* weights') / sum(weights);
end

% Function to configure plot
function configureplot()
    grid on;
    axis equal;
    set(gca, 'YDir', 'reverse');
    xlabel('X Position (cm)');
    ylabel('Y Position (cm)');
    legend('Location', 'northwest');
    xlim([0 600]);
    ylim([0 600]);
end

修复结果

采纳建议后,已成功在图中绘制出分段路径。
修复后效果


内容的提问来源于Stack Exchange,提问作者Michael Liang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 21:45:54