CADViewComponent/src/createBoard.ts

143 lines
4.0 KiB
TypeScript
Raw Normal View History

import * as THREE from 'three';
import { LineSegments, Mesh } from 'three';
import { polar } from './GeUtils';
import { boardMaterial, edgeMaterial } from './Material';
import { RotateUVs } from './RotateUV';
//解析二维圆弧类.
export class Arc2d
{
m_StartAn: number;
m_EndAn: number;
m_StartPoint: THREE.Vector2;
m_EndPoint: THREE.Vector2;
m_Center: THREE.Vector2;
m_Radius: number;
constructor(p1: THREE.Vector2, p2: THREE.Vector2, bul: number)
{
this.m_StartPoint = p1.clone();
this.m_EndPoint = p2.clone();
let vec: THREE.Vector2 = p2.clone().sub(p1);
let len = vec.length();
let an = vec.angle();
this.m_Radius = len / Math.sin(2 * Math.atan(bul)) / 2;
let allAngle = Math.atan(bul) * 4;
let delDis = bul * len / 2;
let toDis = this.m_Radius - delDis;
an += Math.PI * 0.5;
this.m_Center = p1.clone().add(p2);
this.m_Center.multiplyScalar(0.5);
polar(this.m_Center, an, toDis);
this.m_StartAn = p1.clone().sub(this.m_Center).angle();
this.m_EndAn = p2.clone().sub(this.m_Center).angle();
if (bul < 0)
{
//一个神奇的特性 它需要这么做
this.m_StartAn -= Math.PI;
this.m_EndAn -= Math.PI;
}
}
}
//创建轮廓 通过点表和凸度
export function createPath(pts: THREE.Vector2[], buls: number[], shapeOut?: THREE.Shape): THREE.Shape
{
let shape = shapeOut || new THREE.Shape();
if (pts.length === 0) return shape;
let firstPt = pts[0];
shape.moveTo(firstPt.x, firstPt.y);
for (let i = 0; i < pts.length - 1; i++)
{
let nextPt = pts[i + 1];
if (buls[i] == 0)
{
shape.lineTo(nextPt.x, nextPt.y)
}
else
{
let pt = pts[i];
//参考
//http://www.dorodnic.com/blog/tag/three-js/ 绘制一个齿轮
//https://www.kirupa.com/html5/drawing_circles_canvas.htm //html5
let arc2 = new Arc2d(pt, nextPt, buls[i]);
let cen = arc2.m_Center;
shape.absarc(cen.x, cen.y, arc2.m_Radius, arc2.m_StartAn, arc2.m_EndAn, buls[i] < 0);
}
}
return shape;
}
export function getVec(data: object): THREE.Vector3
{
return new THREE.Vector3(data["x"], data["y"], data["z"]);
}
//创建板件 暂时这么写
export function createBoard(boardData: object)
{
let pts: THREE.Vector2[] = new Array();
let buls: number[] = new Array();
let boardPts = boardData["Pts"];
let boardBuls = boardData["Buls"];
let boardHeight = boardData["H"];
let boardMat = new THREE.Matrix4();
let matInv: THREE.Matrix4 = new THREE.Matrix4();
//InitBoardMat
{
let xD = getVec(boardData["XVec"]);
let yD = getVec(boardData["YVec"]);
let ZD = getVec(boardData["ZVec"]);
let pBase = getVec(boardData["BasePoint"]);
boardMat.makeBasis(xD, yD, ZD);
boardMat.setPosition(pBase);
matInv.getInverse(boardMat, true);
}
for (let i = 0; i < boardPts.length; i++)
{
let pt = getVec(boardPts[i]);
pt.applyMatrix4(matInv);
pts.push(new THREE.Vector2(pt.x, pt.y));
buls.push(boardBuls[i]);
}
let sp = createPath(pts, buls);
let extrudeSettings = {
steps: 1,
bevelEnabled: false,
amount: boardHeight
};
let ext = new THREE.ExtrudeGeometry(sp, extrudeSettings);
ext.computeBoundingSphere();
ext.computeBoundingBox();
ext.translate(0, 0, -boardHeight)
ext.applyMatrix(boardMat);
if (boardData["BoardName"] === "地脚线")
{
RotateUVs(ext);
}
let mesh = new THREE.Mesh(ext, boardMaterial);
return mesh;
}
export function createTemplateBoard(brDataList: any[])
{
return brDataList.map(brData => createBoard(brData));
}
export function createEdge(board: Mesh): LineSegments
{
let edge = new THREE.EdgesGeometry(board.geometry, 1);
return new LineSegments(edge, edgeMaterial);
}