很多bim轻量化平台应该都有测量这个功能,什么距离啊,角度测量呀,里面比较复杂的还是面积测量这块,其他就比较简单了;
首先面积测量你得考虑是否共面,还得兼容凹凸多边形
先看看效果吧
逻辑很简单:1.只有模型才可以点击,空白的地方不能测量的(其实就是碰撞检测)2.鼠标抬起是确定一个点,鼠标移动是你绘制线 3.三个点确定一个平面 4.把任意多变形拆分成三角形来计算面积
实现逻辑都在这里,画线是用three的MeshLine画的,其实主要看面积测量逻辑就ok了,语言是ts写的,具体细节交流私下
@Injectable()
export class MeasureAreaService {
private sprite = null;
private line_measure = null;
private currentPoint = null;
private currentCount = 0;
private firstPoint = null;
private origin = null;
private downTime = 0;
private upTime = 0;
private onmousemoveSubscription = null;
private onmousedownSubscription = null;
private onmouseupSubscription = null;
private mousewheelSubscription = null;
private needHighLightSubscription = null;
private pointList = new Array < THREE.Vector3 > ();
private keydownEvent = null;
private aParameter = 0;
private bParameter = 0;
private cParameter = 0;
private dParameter = 0;
private measureItems: any[] = [];
private dashedLine;
public close() {
if (this.onmousemoveSubscription) {
this.onmousemoveSubscription.unsubscribe();
}
if (this.onmousedownSubscription) {
this.onmousedownSubscription.unsubscribe();
}
if (this.onmouseupSubscription) {
this.onmouseupSubscription.unsubscribe();
}
if (this.mousewheelSubscription) {
this.mousewheelSubscription.unsubscribe();
}
if (this.needHighLightSubscription) {
this.needHighLightSubscription.unsubscribe();
}
if (this.sprite) {
this.viewerService.highlightScene.remove(this.sprite);
}
if (this.keydownEvent) {
(window as any).removeEventListener('keydown', this.keydownEvent, false);
}
//this.state = OptState.Idle;
this.clear();
//this.rendererService.needHighLightRender.emit(true);
this.measureItemsManagerService.close();
}
public open() {
this.keydownEvent = (event) => {
if (event.keyCode === 27) {
if (this.currentCount >= 3) {
if (this.currentPoint.x == this.firstPoint.x &&
this.currentPoint.y == this.firstPoint.y &&
this.currentPoint.z == this.firstPoint.z) {
//防止闪烁
if (this.measureItemsManagerService.getCurrentMeasureItem()) {
this.measureItemsManagerService.deactiveCurrentMeasureLine();
}
//实例化线条
this.measureItemsManagerService.getCurrentMeasureItem().active = true;
this.measureItemsManagerService.createMeasureItem().active = true;
} else {
this.viewerService.highlightScene.remove(this.measureItemsManagerService.getCurrentMeasureItem().highlightLine.getHighlightLine());
let highlightLine = new HighLightLine(this.measureItemsManagerService.getHighlightMaterial());
let measureItem = this.measureItemsManagerService.createMeasureItem();
measureItem.setHighlightLine(highlightLine);
me