grok:用兩條線段是否相交的辦法來判斷兩個多邊形是否相交

一些和AI相关的讨论
回复
头像
ejsoon
圈圈精英
圈圈精英
帖子: 3569
注册时间: 2022年 11月 18日 17:36
为圈友点赞: 149 次
被圈友点赞: 164 次
联系:

grok:用兩條線段是否相交的辦法來判斷兩個多邊形是否相交

帖子 ejsoon »

兩個多邊形的端點為(ax0,ay0;ax1,ay1;ax2,ay2;ax3,ay3;...)和(bx0,by0;bx1,by1;bx2,by2;bx3,by3;...),寫一個js方法,循環判斷兩個多邊形是否有邊相交。當出現相交則停止判斷,返回true。否則返回false。判斷點是否在線上的公差為z。

代码: 全选

以下是一個 JavaScript 方法,用於判斷兩個多邊形是否有邊相交。方法會遍歷兩個多邊形的所有邊,並使用前述的線段相交算法進行檢查。如果發現相交,則立即返回 `true`;否則,檢查完所有邊後返回 `false`。這裡還加入了公差 `z`,用於處理浮點數計算的精度問題(例如判斷點是否在線上時的近似處理)。

```javascript
// 判斷單一線段是否相交(帶公差 z)
function doSegmentsIntersect(x0, y0, x1, y1, x2, y2, x3, y3, z) {
    // 計算叉積
    function crossProduct(x1, y1, x2, y2, x3, y3) {
        return (x2 - x1) * (y3 - y1) - (y2 - y1) * (x3 - x1);
    }

    // 檢查範圍是否重疊
    function overlap(min1, max1, min2, max2) {
        return min1 - z <= max2 && min2 - z <= max1;
    }

    const d1 = crossProduct(x0, y0, x1, y1, x2, y2);
    const d2 = crossProduct(x0, y0, x1, y1, x3, y3);
    const d3 = crossProduct(x2, y2, x3, y3, x0, y0);
    const d4 = crossProduct(x2, y2, x3, y3, x1, y1);

    // 一般情況:符號相反表示相交(考慮公差 z)
    if ((d1 > z && d2 < -z) || (d1 < -z && d2 > z)) {
        if ((d3 > z && d4 < -z) || (d3 < -z && d4 > z)) {
            return true;
        }
    }

    // 共線情況:所有叉積接近 0(在公差 z 內)
    if (Math.abs(d1) <= z && Math.abs(d2) <= z && Math.abs(d3) <= z && Math.abs(d4) <= z) {
        const minX1 = Math.min(x0, x1);
        const maxX1 = Math.max(x0, x1);
        const minY1 = Math.min(y0, y1);
        const maxY1 = Math.max(y0, y1);
        const minX2 = Math.min(x2, x3);
        const maxX2 = Math.max(x2, x3);
        const minY2 = Math.min(y2, y3);
        const maxY2 = Math.max(y2, y3);

        return overlap(minX1, maxX1, minX2, maxX2) && overlap(minY1, maxY1, minY2, maxY2);
    }

    return false;
}

// 判斷兩個多邊形是否有邊相交
function doPolygonsIntersect(polygonA, polygonB, z = 1e-10) {
    // 將多邊形轉為邊的起點和終點數組
    const edgesA = [];
    const edgesB = [];
    
    // 多邊形 A 的邊
    for (let i = 0; i < polygonA.length; i++) {
        const next = (i + 1) % polygonA.length; // 閉合多邊形
        edgesA.push({
            x0: polygonA[i][0],
            y0: polygonA[i][1],
            x1: polygonA[next][0],
            y1: polygonA[next][1]
        });
    }
    
    // 多邊形 B 的邊
    for (let i = 0; i < polygonB.length; i++) {
        const next = (i + 1) % polygonB.length; // 閉合多邊形
        edgesB.push({
            x0: polygonB[i][0],
            y0: polygonB[i][1],
            x1: polygonB[next][0],
            y1: polygonB[next][1]
        });
    }

    // 遍歷所有邊對,檢查是否相交
    for (const edgeA of edgesA) {
        for (const edgeB of edgesB) {
            if (doSegmentsIntersect(
                edgeA.x0, edgeA.y0, edgeA.x1, edgeA.y1,
                edgeB.x0, edgeB.y0, edgeB.x1, edgeB.y1,
                z
            )) {
                return true; // 一旦發現相交,立即返回 true
            }
        }
    }

    return false; // 無相交邊
}

// 測試範例
const polygonA = [[0, 0], [2, 0], [2, 2], [0, 2]]; // 矩形
const polygonB = [[1, 1], [3, 1], [3, 3], [1, 3]]; // 另一矩形,相交
const polygonC = [[3, 3], [5, 3], [5, 5], [3, 5]]; // 不相交

console.log(doPolygonsIntersect(polygonA, polygonB, 1e-10)); // true
console.log(doPolygonsIntersect(polygonA, polygonC, 1e-10)); // false
```

### 代碼說明
1. **`doSegmentsIntersect`**:
   - 修改了之前的線段相交函數,加入公差 `z`,用於處理浮點數精度問題。
   - 當叉積的絕對值小於 `z` 時,視為 0(共線);大於 `z` 或小於 `-z` 用於符號判斷。
   - 共線時,使用範圍檢查,並在比較時考慮公差。

2. **`doPolygonsIntersect`**:
   - 輸入:兩個多邊形的頂點數組(格式為 `[[x0, y0], [x1, y1], ...]`)和公差 `z`(默認為 `1e-10`)。
   - 將多邊形分解為邊的集合,考慮閉合(首尾相連)。
   - 雙重循環遍歷兩個多邊形的所有邊對,調用 `doSegmentsIntersect` 檢查是否相交。
   - 一旦發現相交,立即返回 `true`;否則遍歷完後返回 `false`。

3. **公差 `z`**:
   - 用於處理浮點數計算的誤差,例如點是否在線上的判斷。
   - 默認值 `1e-10` 適用於大多數情況,可根據需要調整。

### 測試案例
- `polygonA` 和 `polygonB` 是兩個相交的矩形,返回 `true`。
- `polygonA` 和 `polygonC` 是不相交的矩形,返回 `false`。

這個方法高效且穩定,適用於任意凸或凹多邊形的邊相交檢測。
https://ejsoon.vip/
弈趣極光:享受思維樂趣
头像
ejsoon
圈圈精英
圈圈精英
帖子: 3569
注册时间: 2022年 11月 18日 17:36
为圈友点赞: 149 次
被圈友点赞: 164 次
联系:

Re: grok:用兩條線段是否相交的辦法來判斷兩個多邊形是否相交

帖子 ejsoon »

判斷點在線段的右側:

代码: 全选

function isPointRightOfLine(x0, y0, x1, y1, x2, y2, x3, y3, zag = 1e-6) {
    // 確保 zag 是正值,若未提供則使用默認值 1e-6
    zag = Math.abs(zag) || 1e-6;
    
    // 線段一的方向向量 (dx1, dy1)
    const dx1 = x1 - x0;
    const dy1 = y1 - y0;
    
    // 從 (x2,y2) 到 (x3,y3) 的向量 (dx2, dy2)
    const dx2 = x3 - x2;
    const dy2 = y3 - y2;
    
    // 使用 atan2 計算兩個向量的角度
    const angle1 = Math.atan2(dy1, dx1); // 線段一的方向(定義為「上方」)
    const angle2 = Math.atan2(dy2, dx2); // 從 (x2,y2) 到 (x3,y3) 的方向
    
    // 計算角度差 (範圍在 -π 到 π 之間)
    let angleDiff = angle2 - angle1;
    if (angleDiff > Math.PI) angleDiff -= 2 * Math.PI;
    if (angleDiff < -Math.PI) angleDiff += 2 * Math.PI;
    
    // 考慮角度公差 zag,右側的角度差應小於 -zag
    return angleDiff < -zag;
}

// 測試範例
console.log(isPointRightOfLine(0, 0, 0, 1, 0, 0, 1, 0));   // true (右側)
console.log(isPointRightOfLine(0, 0, 0, 1, 0, 0, -1, 0));  // false (左側)
console.log(isPointRightOfLine(0, 0, 1, 0, 0, 0, 0, 1));   // true (右側)
console.log(isPointRightOfLine(0, 0, 1, 0, 0, 0, 0, -1));  // false (左側)
// 測試極小角度差
console.log(isPointRightOfLine(0, 0, 0, 1, 0, 0, 1e-7, 0)); // true (仍判為右側)
console.log(isPointRightOfLine(0, 0, 0, 1, 0, 0, -1e-7, 0)); // false (仍判為左側)
https://ejsoon.vip/
弈趣極光:享受思維樂趣
头像
ejsoon
圈圈精英
圈圈精英
帖子: 3569
注册时间: 2022年 11月 18日 17:36
为圈友点赞: 149 次
被圈友点赞: 164 次
联系:

Re: grok:用兩條線段是否相交的辦法來判斷兩個多邊形是否相交

帖子 ejsoon »

給出一個js方法,通過兩個線段的端點坐標判斷它們是否平行,用到atan2方法,夾角公差為zag。zag是角度單位。

代码: 全选

function areLinesParallel(x1, y1, x2, y2, x3, y3, x4, y4, zag) {
    // 計算第一條線段的方向角度(弧度)
    const angle1 = Math.atan2(y2 - y1, x2 - x1);
    // 計算第二條線段的方向角度(弧度)
    const angle2 = Math.atan2(y4 - y3, x4 - x3);
    
    // 計算兩條線段的夾角(取絕對值)
    let angleDiff = Math.abs(angle1 - angle2);
    
    // 考慮平行線可能方向相反的情況(180度差)
    if (angleDiff > Math.PI) {
        angleDiff = 2 * Math.PI - angleDiff;
    }
    
    // 將輸入的角度公差轉換為弧度
    const toleranceInRadians = zag * Math.PI / 180;
    
    // 如果夾角小於公差值,則認為平行
    return angleDiff <= toleranceInRadians;
}

// 示例用法:
console.log(areLinesParallel(0, 0, 2, 2, 0, 2, 2, 4, 5));  // true (5度公差,兩條線段斜率相同)
console.log(areLinesParallel(0, 0, 1, 1, 0, 0, 1, 0, 5));  // false (45度夾角大於5度公差)
https://ejsoon.vip/
弈趣極光:享受思維樂趣
头像
ejsoon
圈圈精英
圈圈精英
帖子: 3569
注册时间: 2022年 11月 18日 17:36
为圈友点赞: 149 次
被圈友点赞: 164 次
联系:

wordpress當留言有人回覆時,發送通知郵件的模板在哪設置?

帖子 ejsoon »

grok:

代码: 全选

在 WordPress 中,當留言有人回覆時發送的通知郵件模板並沒有直接提供一個內建的編輯界面來修改其內容,因為這些通知郵件是由 WordPress 核心程式碼生成的。不過,你可以通過以下幾種方法自定義這些通知郵件的模板或內容:

---

### 方法 1:使用插件自定義通知郵件
最簡單的方法是使用插件來修改和管理通知郵件模板。以下是一些推薦的插件:

1. **Better Notifications for WordPress**
   - 安裝並啟用插件後,前往 WordPress 後台的「Notifications」設置。
   - 創建一個新的通知,選擇觸發條件為「Comment Reply」(留言回覆)。
   - 在模板編輯器中自定義郵件的主題(Subject)、內容(Body),甚至可以加入動態變量(如評論者姓名、文章標題等)。
   - 保存後,該插件會覆蓋 WordPress 默認的通知郵件。

2. **Email Templates**
   - 這個插件允許你設計漂亮的 HTML 郵件模板,並應用於所有 WordPress 發送的郵件,包括留言回覆通知。
   - 在後台設置中調整樣式和內容。

3. **WP Mail SMTP**
   - 雖然主要是用來配置 SMTP,但它也提供了一些基本的郵件自定義功能,可以間接影響通知的外觀。

**優點**:無需編寫代碼,適合新手。

---

### 方法 2:通過代碼修改通知模板
如果你熟悉 PHP,可以通過過濾器(filter)修改 WordPress 的通知郵件內容。這些通知由 `wp_notify_postauthor()` 和 `wp_notify_moderator()` 函數控制,你可以用 `wp_mail` 過濾器來調整。

#### 步驟:
1. **編輯主題的 `functions.php` 文件**:
   - 在你的 WordPress 主題文件夾中找到 `functions.php`,或者使用子主題以避免更新時被覆蓋。
   - 添加以下代碼:

   ```php
   add_filter('wp_mail', 'customize_comment_reply_email', 10, 1);

   function customize_comment_reply_email($args) {
       // 檢查是否為評論回覆通知
       if (strpos($args['subject'], 'Comment') !== false && strpos($args['message'], 'In reply to') !== false) {
           // 自定義郵件主題
           $args['subject'] = '有人回覆了您的留言 - ' . get_bloginfo('name');

           // 自定義郵件內容
           $args['message'] = "親愛的用戶,\n\n";
           $args['message'] .= "有人在 [" . get_bloginfo('name') . "] 回覆了您的留言。\n";
           $args['message'] .= "查看詳情: " . get_permalink($comment->comment_post_ID) . "#comment-" . $comment_id . "\n\n";
           $args['message'] .= "感謝您的參與!\n";
           $args['message'] .= "來自 " . get_bloginfo('name') . " 團隊";
       }
       return $args;
   }
   ```

2. **保存並測試**:
   - 上傳修改後的文件,然後在網站上測試留言回覆功能,檢查郵件是否按你的設計發送。

**注意**:
- 你需要根據實際需求調整 `$args['subject']` 和 `$args['message']` 的內容。
- 如果需要獲取更多動態數據(如評論者姓名),可以結合 `get_comment()` 函數。

---

### 方法 3:覆蓋核心郵件模板(進階)
WordPress 的郵件模板直接硬編碼在核心文件中(例如 `wp-includes/pluggable.php` 中的 `wp_notify_postauthor()`),但不建議直接修改核心文件,因為更新時會被覆蓋。更好的方法是:
- 使用插件或代碼(如方法 2)完全重寫這些函數的行為。

---

### 默認設置位置
如果你只是想調整基本的通知開關(而不是模板內容),可以:
1. 前往 WordPress 後台的「設置」>「討論」。
2. 在「電子郵件通知我」部分,勾選「任何人發佈評論時」或「評論需要審核時」。
3. 這些設置只控制是否發送通知,而不涉及模板本身。

---

### 總結
- **簡單需求**:用插件(如 Better Notifications for WordPress)。
- **進階自定義**:修改 `functions.php` 添加過濾器。
- **測試**:修改後記得測試郵件發送,確保格式和內容符合預期。

如果你需要更具體的代碼範例或插件推薦,可以告訴我你的 WordPress 版本或其他細節,我再幫你優化!
https://ejsoon.vip/
弈趣極光:享受思維樂趣
头像
ejsoon
圈圈精英
圈圈精英
帖子: 3569
注册时间: 2022年 11月 18日 17:36
为圈友点赞: 149 次
被圈友点赞: 164 次
联系:

Re: grok:用兩條線段是否相交的辦法來判斷兩個多邊形是否相交

帖子 ejsoon »

如何離線打包npm:

代码: 全选

要將一個 npm 安裝包及其所有依賴項安裝在本地並離線運行,且所有文件集中在同一個文件夾中,你需要將包及其依賴項打包並組織好。以下是具體步驟,以 `markmap-autoloader` 為例:

---

### 步驟

1. **創建項目並安裝所需包**
   - 在本地創建一個新文件夾,例如 `my-offline-markmap`。
   - 打開終端,進入該文件夾:
     ```bash
     cd my-offline-markmap
     ```
   - 初始化一個 npm 項目:
     ```bash
     npm init -y
     ```
   - 安裝 `markmap-autoloader`:
     ```bash
     npm install markmap-autoloader
     ```

2. **確認並安裝所有依賴項**
   - `markmap-autoloader` 可能依賴其他包(如 `markmap-lib` 或 `d3`)。你可以查看 `node_modules/markmap-autoloader/package.json` 中的 `dependencies` 字段,確認是否有依賴。
   - 如果有依賴,手動安裝它們,例如:
     ```bash
     npm install markmap-lib d3
     ```
   - 現在,所有相關文件都位於 `node_modules` 文件夾中。

3. **使用打包工具合併文件**
   - 要將所有文件合併到單個文件夾並確保離線運行,可以使用打包工具(如 `webpack` 或 `rollup`)將主包及其依賴項打包成一個獨立的 `.js` 文件。
   - 安裝 `webpack`:
     ```bash
     npm install --save-dev webpack webpack-cli
     ```

   - 創建一個入口文件(例如 `index.js`):
     ```javascript
     // index.js
     import 'markmap-autoloader';
     ```
   - 配置 `webpack`。創建 `webpack.config.js`:
     ```javascript
     const path = require('path');

     module.exports = {
       entry: './index.js',
       output: {
         filename: 'markmap-bundle.js',
         path: path.resolve(__dirname, 'dist'),
       },
       mode: 'production',
     };
     ```
   - 運行打包命令:
     ```bash
     npx webpack
     ```
   - 打包完成後,`dist/markmap-bundle.js` 將包含 `markmap-autoloader` 及其所有依賴項。

4. **將文件集中到單個文件夾**
   - 創建一個新文件夾(例如 `offline-files`),將打包好的 `markmap-bundle.js` 移動到該文件夾:
     ```bash
     mkdir offline-files
     mv dist/markmap-bundle.js offline-files/
     ```
   - 如果你的項目需要其他靜態文件(如 CSS 或 HTML),也將它們放入 `offline-files`。

5. **創建 HTML 文件並測試**
   - 在 `offline-files` 中創建一個 `index.html`:
     ```html
     <!DOCTYPE html>
     <html>
     <head>
       <title>Offline Markmap</title>
     </head>
     <body>
       <div id="mindmap"></div>
       <script src="./markmap-bundle.js"></script>
       <!-- 如果需要,添加初始化代碼 -->
       <script>
         // 示例:假設 markmap-autoloader 自動運行
         console.log("Markmap loaded offline");
       </script>
     </body>
     </html>
     ```
   - 斷開網絡,通過瀏覽器打開 `index.html`,確認功能正常。

6. **驗證離線運行**
   - 確保所有功能在無網絡的情況下都能工作。如果缺少某些依賴,檢查 `markmap-autoloader` 的文檔,確認是否需要額外的配置或文件。

---

### 注意事項
- **依賴問題**:如果 `markmap-autoloader` 有動態加載的資源(例如通過 CDN 載入的腳本),你需要檢查其源碼並手動下載這些資源,然後修改引用指向本地文件。
- **打包工具選擇**:這裡使用的是 `webpack`,你也可以使用 `rollup` 或 `esbuild`,它們更輕量,具體取決於你的需求。
- **文件大小**:打包後的 `markmap-bundle.js` 可能包含所有依賴,導致文件較大,但這是離線使用的代價。

---

### 最終文件結構
完成後,你的 `offline-files` 文件夾可能如下:
```
offline-files/
├── index.html
└── markmap-bundle.js
```

現在,你可以在任何沒有網絡的環境中,將這個文件夾複製到其他設備並運行 `index.html`,實現完全離線使用。如果有特定問題(例如某功能不工作),告訴我,我可以幫你進一步調整!
https://ejsoon.vip/
弈趣極光:享受思維樂趣
回复

在线用户

正浏览此版面之用户: 没有注册用户 和 1 访客