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

检测并统计三角形群每次穿越环境时穿过矩形的三角形数量

Alright, let's tackle this problem of counting how many triangles in your swarm cross through the rectangle. It sounds like your hasFoundFood method isn't cutting it—probably because it's not tracking state changes properly, which is key for counting crossings instead of just checking if a triangle is inside the rectangle. Here's a solid, edge-case-proof approach:

Core Approach & Implementation Steps

First, let's clarify what counts as a "crossing": we'll define it as a triangle moving from completely outside the rectangle to inside or intersecting with the rectangle in a single frame. This avoids double-counting triangles that linger inside the rectangle.

1. Add State Tracking to Each Triangle

Each triangle needs to remember its previous frame's position relative to the rectangle to detect when a crossing happens. Add these boolean properties to your triangle class:

class Triangle {
    // Existing properties: position, vertices, movement direction, etc.
    private boolean wasInsideRectangle = false;
    private boolean isInsideRectangle = false;

    // Call this every frame to update the triangle's state relative to the rectangle
    public void updateRectangleState(Rectangle targetRect) {
        // Save last frame's state before checking the current one
        wasInsideRectangle = isInsideRectangle;
        // Update current state by checking if the triangle intersects/is inside the rectangle
        isInsideRectangle = doesTriangleIntersectRectangle(targetRect);
    }
}

2. Implement a Robust Intersection Check

Replace your hasFoundFood logic with a method that properly detects if a triangle is inside or intersecting the rectangle. This covers two scenarios:

  • At least one triangle vertex is inside the rectangle
  • Any edge of the triangle crosses any edge of the rectangle

Here's a sample implementation:

private boolean doesTriangleIntersectRectangle(Rectangle rect) {
    // First check if any vertex is inside the rectangle
    for (Point vertex : this.getVertices()) {
        if (rect.contains(vertex)) {
            return true;
        }
    }

    // If no vertices are inside, check if any triangle edges cross rectangle edges
    Line[] triangleEdges = this.getEdges(); // Returns 3 Line objects for the triangle's sides
    Line[] rectEdges = rect.getEdges(); // Returns 4 Line objects for the rectangle's sides

    for (Line triEdge : triangleEdges) {
        for (Line rectEdge : rectEdges) {
            if (doSegmentsIntersect(triEdge, rectEdge)) {
                return true;
            }
        }
    }

    return false;
}

// Helper method to check if two line segments intersect (use standard cross product logic)
private boolean doSegmentsIntersect(Line a, Line b) {
    // Implement the standard line segment intersection algorithm here
    // Key steps: check bounding boxes overlap first, then use cross products to verify direction
}

3. Count Crossings & Manage Swarm Lifecycle

In your main update loop, you'll:

  1. Update each triangle's rectangle state
  2. Check for state changes (from outside to inside) to count crossings
  3. Reset the swarm and tracking state when the entire group leaves the environment
// In your swarm manager class
private int totalCrossings = 0;
private List<Triangle> triangleSwarm = new ArrayList<>();
private Rectangle environmentBounds; // Your overall environment area
private Rectangle targetRectangle; // The rectangle to track crossings through

public void updateFrame() {
    // Step 1: Update all triangles' rectangle states
    for (Triangle tri : triangleSwarm) {
        tri.updateRectangleState(targetRectangle);
    }

    // Step 2: Count new crossings (triangle moved from outside to inside)
    for (Triangle tri : triangleSwarm) {
        if (!tri.wasInsideRectangle && tri.isInsideRectangle) {
            totalCrossings++;
            // Optional: Log which triangle crossed, timestamp, etc.
            System.out.println("Triangle crossed! Total count: " + totalCrossings);
        }
    }

    // Step 3: Check if the entire swarm is outside the environment
    boolean isSwarmOutside = true;
    for (Triangle tri : triangleSwarm) {
        if (environmentBounds.contains(tri.getBoundingBox())) {
            isSwarmOutside = false;
            break;
        }
    }

    if (isSwarmOutside) {
        // Regenerate the swarm
        triangleSwarm = generateNewSwarm(20);
        // Reset tracking states for all new triangles
        for (Triangle tri : triangleSwarm) {
            tri.wasInsideRectangle = false;
            tri.isInsideRectangle = false;
        }
        // Optional: Reset the crossing count if you want to track per-swarm crossings
        // totalCrossings = 0;
    }
}

4. Key Fixes Over hasFoundFood

The main issue with using hasFoundFood is that it only checks the current state (is the triangle inside?), not the change in state (did it just enter?). This leads to:

  • Double-counting triangles that stay inside the rectangle for multiple frames
  • Missing crossings where the triangle only intersects the rectangle's edge without fully entering

By tracking wasInside and isInside, you only count the exact moment a triangle crosses into the rectangle.

内容的提问来源于stack exchange,提问作者totalthomas

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:40:25