npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

rm-wall-snap-3d

v1.4.8

Published

3D物体墙体吸附与位置修正引擎 - 支持家具、电源等自动适配墙体

Downloads

3,660

Readme

rm-wall-snap-3d

3D物体墙体吸附与位置修正引擎 - 支持家具、电源等自动适配墙体

📦 正式版本 1.4.5

更新日期: 2026-06-03 主要变更:

  • 移除 THREE.js 依赖,包体积减少 30%
  • 移除 1cm 吸附偏移量,物体直接贴墙
  • 新增 hotelJson 完整模式:直接传入酒店 JSON,自动提取墙体 + 旋转 + 格式转换
  • 重要变更contour 现在返回原始数据,quadContour 返回吸附后的新轮廓
  • wallshotelJson 字段自动兼容
  • positionArr 必须传入,用作墙体方向判断依据,现在也会原样返回
  • 重要contour 字段现在是必填项
  • 前端无需筛选墙体数据,npm 包内部自动处理
  • 纯 JS 输出,无 TypeScript 类型导出
  • 所有 import 都带 .js 后缀

环境要求

  • Node.js: >= 16.0.0
  • 模块系统: ESM (import/export)

安装

npm install rm-wall-snap-3d

导出版本

import { VERSION } from 'rm-wall-snap-3d';
console.log(VERSION); // 例如: "1.4.3"

使用

推荐用法(hotelJson 模式)

import { snapToWalls } from 'rm-wall-snap-3d';

// 直接传入完整的酒店 JSON 数据
const response = snapToWalls({
  items: [
    {
      obj_id: 'socket_001',
      category: 'socket',
      box: {
        isBox3: true,
        min: { x: 1.0, y: 2.0, z: 1.4 },
        max: { x: 1.085, y: 2.085, z: 1.485 }
      },
      position: { x: 1.0425, y: 2.0425, z: 1.4425 },
      size: { x: 0.085, y: 0.085, z: 0.085 },
      contour: [{ x, y, z }, ...],    // 轮廓点(优先使用)
      direction: { x: 0, y: 1, z: 0 },
      positionArr: [{ x, y, z }]      // 【必填】物体在墙内侧的位置点
    }
  ],
  // 直接传 hotelJson(含 walls、center、angle)
  hotelJson: {
    center: { x: 0, y: 0 },
    angle: 0.5,
    walls: [
      { start: { x: 0, y: 0 }, end: { x: 1, y: 0 }, thickness: 0.12, height: 2.8 }
    ]
  }
});

if (response.success) {
  console.log(response.message);
  response.data.results.forEach(result => {
    if (result.snapped) {
      console.log(`✅ ${result.obj_id} 吸附成功`);
      console.log('新位置:', result.position);
      console.log('匹配墙体:', result.quadContour);
    }
  });
}

直接传 walls 模式

const response = snapToWalls({
  items: [...],
  walls: [
    // 格式1:内部格式(center/normal)
    { center: { x, y, z }, normal: { x, y, z } },
    // 格式2:前端格式(start/end)
    { start: { x, y }, end: { x, y }, thickness: 0.12, height: 2.8 }
  ]
});

两种模式均无需传入 THREE.js 实例。

数据格式

Item(物品)

{
  obj_id: string;                // 唯一标识
  category: string;              // 类型:socket, switch, cabinet, air conditioner 等
  box: {
    isBox3: boolean;
    min: { x, y, z };            // 包围盒最小点
    max: { x, y, z };            // 包围盒最大点
  };
  position: { x, y, z };         // 中心位置
  size: { x, y, z };             // 尺寸
  contour?: { x, y, z }[];       // 轮廓点数组(优先使用)
  vertices?: number[];           // 顶点数组(flattened,无 contour 时自动转换)
  direction: { x, y, z };        // 朝向
  /** 【必填】物体在墙内侧的位置点 */
  positionArr: { x, y, z }[];
}

⚠️ positionArr 必须传入:引擎通过该点判断物体在墙体内侧还是外侧,从而决定吸附方向。缺少该字段会导致吸附失败(返回 null)。

Wall(墙体)

本包自动支持两种墙体数据格式:

格式 1:前端格式(start/end) — 推荐

{
  start: { x: number, y: number, z?: number };  // 起始点
  end: { x: number, y: number, z?: number };    // 结束点
  thickness?: number;                            // 墙体厚度(默认 0.12)
  height?: number;                               // 墙体高度(默认 3.0)
}

格式 2:内部格式(center/normal)

{
  center: { x, y, z };       // 墙面中心点
  normal: { x, y, z };       // 墙面法向量
  innerSurface?: { x, y, z }; // 内表面(可选,自动计算)
  outerSurface?: { x, y, z }; // 外表面(可选,自动计算)
}

hotelJson 格式

{
  center: { x: number, y: number };     // 户型中心点(用于旋转校正)
  angle: number;                         // 旋转角度(弧度,用于旋转校正)
  height: number;                        // 墙体高度
  walls: Array;                         // 墙体数组(start/end 格式)
  rooms?: any[];                         // 房间信息
  // ... 其他字段
}

传入 hotelJson 后,npm 包会自动执行:提取墙体 → 旋转校正 → 格式转换。

Result(结果)

{
  obj_id: string;                           // 物体唯一标识(不变)
  category: string;                         // 物体类型(不变)
  snapped: boolean;                         // 是否成功吸附
  distance: number;                         // 与墙面的距离

  // 不变字段
  box: { isBox3: boolean; min: Object; max: Object };
  size: Object;

  // 吸附后更新
  position: Object;                         // 吸附后的新位置
  direction: Object;                        // 墙面内侧方向
  contour?: Array;                          // 【不变】原始轮廓点(前端传入的值)
  positionArr?: Array;                      // 【不变】物体在墙内侧的位置点数组(前端传入的值)
  vertices?: Array;                         // 【不变】原始顶点数组(前端传入的值)
  rotationAngle?: number;                   // 旋转角度(弧度)
  backFaceCenter?: Object;                  // 物体背面中心点
  rawContour?: Array;                       // 原始轮廓(旋转位移前)

  /** 【重要】吸附后的新轮廓点(旋转+位移后) */
  quadContour?: Array;
}

吸附逻辑

整体流程:墙体提取格式转换找到最近墙旋转位移

  1. 墙体数据准备:自动从 wallshotelJson.walls 提取墙体,支持自动旋转校正
  2. 找到最近的墙面:计算物体中心到各墙面的最短距离
  3. 旋转物体:让物体长边与墙面方向完全平行
  4. 计算背面中心点:从轮廓中心出发,沿墙面外侧移动物体深度的一半
  5. 位移:让背面中心点贴到墙体内表面(无额外偏移)
  6. 保持原始高度:Z 轴坐标保持不变

墙面内外侧判断

使用 positionArr(物体在墙内侧的位置点)来判断该物体应吸附到墙的哪一侧:

  • 计算位置点到墙面的投影方向
  • 投影为正 → 使用墙面法线方向
  • 投影为负 → 使用法线反方向

positionArr 是方向判断的关键字段,必须正确传入。

支持的物品类型

| 类型 | 行为 | |------|------| | socket(电源) | 贴墙 | | switch(开关) | 贴墙 | | air conditioner(空调) | 贴墙 | | cabinet(柜子) | 贴墙 | | table / chair / sofa / bed | 保持原位(不吸附) |

输入字段说明

| 字段 | 是否必填 | 说明 | |------|---------|------| | obj_id | ✅ | 物体的唯一标识符 | | category | ✅ | 物体类型 | | box | ✅ | 包围盒,用于碰撞检测 | | position | ✅ | 物体中心点坐标 | | size | ✅ | 物体的长宽高 | | contour | ✅ | 必填 轮廓点数组(优先使用) | | vertices | ❌ | 顶点数组(无 contour 时自动转换) | | direction | ✅ | 物体的朝向向量 | | positionArr | ✅ | 物体在墙内侧的位置点(方向判断关键) |

输出字段说明

| 字段 | 变化 | 说明 | |------|------|------| | obj_id | ❌ 不变 | 物体的唯一标识符 | | category | ❌ 不变 | 物体类型 | | box | ❌ 不变 | 原始包围盒 | | size | ❌ 不变 | 原始尺寸 | | position | ✅ 更新 | 吸附后的新位置 | | contour | ❌ 不变 | 【原始】前端传入的轮廓点 | | positionArr | ❌ 不变 | 【原始】物体在墙内侧的位置点数组(前端传入的值) | | vertices | ❌ 不变 | 【原始】前端传入的顶点数组 | | direction | ✅ 更新 | 墙面内侧方向 | | snapped | ✅ 新增 | 是否成功吸附 | | distance | ✅ 新增 | 与墙面的距离 | | backFaceCenter | ✅ 新增 | 物体背面中心点 | | quadContour | ✅ 更新 | 【重要】吸附后的新轮廓点(旋转+位移后) | | rawContour | ✅ 新增 | 原始轮廓数据(旋转位移前) | | rotationAngle | ✅ 新增 | 旋转角度(弧度) |

完整导出示例

// 所有可用的导出
import {
  snapToWalls,           // 主要的吸附方法
  WallSnapEngine,        // 类形式的引擎(高级用法)
  VERSION,               // 版本号
  convertHotelJson       // 酒店 JSON 数据转换工具
} from 'rm-wall-snap-3d';

console.log('版本号:', VERSION);

// 使用 convertHotelJson
const hotelData = {
  walls: [...],
  center: { x: 0, y: 0 },
  angle: 0
};
const converted = convertHotelJson(hotelData);
console.log('转换后的数据:', converted);

注意事项

  1. positionArr 必须传入:缺少该字段会导致吸附失败
  2. contour 优先于 vertices:引擎优先使用 contour,没有则从 vertices 自动转换
  3. 无需 THREE.js:引擎使用纯数学计算,不依赖 Three.js
  4. box 和 size 保持不变:用于碰撞检测和显示尺寸
  5. 坐标系:右手坐标系,Z 轴向上
  6. THREE.js 相关代码已全部移除,包体积更小,无需外部注入
  7. 重要变更contour 现在返回原始数据,quadContour 返回吸附后的新轮廓

License

MIT