123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281 |
- import {CADElement, ElementProps} from '../core/element'
- import LinePoint from '../core/linepoint'
- import {point} from '../core/fixedpoint'
- import Line from '../core/wallline'
- import {
- Line as GeoLine,
- lineDis,
- isContainPoint,
- getDisPointLinePoints,
- pointLineDis,
- } from '../geometry'
- import {type} from '../util'
- export interface LineArchProps extends ElementProps {
- [k: string]: any
- linePoints: [point, point],
- attachment: Line,
- minWidth?: number,
- show?: boolean
- }
- /**
- * @category core
- * @subcategory CAD_Architecture
- */
- class LineArch extends CADElement<LineArchProps> {
- linePoints: [LinePoint, LinePoint]
- // 同一线条所有建筑归为一个数组
- static attaArch = new Map<Line, Array<LineArch>>()
- constructor({minWidth = 0.1, deleteWidth = 0.05, show = true, ...args}: LineArchProps) {
- super({...args, show})
- this.zIndex = 1
- this.linePoints = (this.linePoints.map(point => {
- let lp = new LinePoint({...point, renderer: this.renderer}, this.attachment);
- lp.click = () => this.changeSelect(true)
- return lp;
- })) as [LinePoint, LinePoint]
- this.minWidth = minWidth
- this.deleteWidth = deleteWidth
- this.real.setAttribute('class', 'variable')
-
- if (LineArch.attaArch.get(this.attachment)) {
- LineArch.attaArch.get(this.attachment).push(this)
- } else {
- LineArch.attaArch.set(this.attachment, [this])
- }
- this.attachment.update()
- }
- // 设置新的附属线条
- setAttachment(newAttachment: Line = this.attachment) {
- console.error('set new attach')
- if (this.attachment === newAttachment) return;
- let oldArchs = LineArch.attaArch.get(this.attachment)
- let newArchs = LineArch.attaArch.get(newAttachment) ||
- LineArch.attaArch.set(newAttachment, []).get(newAttachment);
- oldArchs.splice(oldArchs.indexOf(this), 1)
- newArchs.push(this)
- this.linePoints.forEach(point => {
- point.line = newAttachment
- })
- this.attachment = newAttachment
- }
-
- // 建筑端点离墙端点限制
- checkPointBorder(point: point, line:GeoLine = this.attachment) :boolean {
- // return !isContainPoint(line, point)
-
- if (lineDis({points: [line.points[0], point]}) < 0.08) {
- return true
- }
- if (lineDis({points: [line.points[1], point]}) < 0.08) {
- return true
- }
- }
- // 点是否在沿线上
- checkPoint(point: point, line:GeoLine = this.attachment) :boolean {
- return !isContainPoint(line, point)
- }
- // 宽度是否合格
- checkWidth(points: [point, point] = this.linePoints) : boolean {
- return lineDis({points}) < this.minWidth
- }
-
- // 检测同一线条所有建筑是否重叠
- checkPointOverlapAttaArch(archs: Array<LineArch> = LineArch.attaArch.get(this.attachment)) : boolean {
- if (archs.length <= 1) return false
- return archs.some(arch =>
- archs.some(carch =>
- arch !== carch && (
- isContainPoint({points: carch.linePoints}, arch.linePoints[0]) ||
- isContainPoint({points: carch.linePoints}, arch.linePoints[1])
- )
- )
- )
- }
- // 检测同一线条所有建筑是否在线上
- checkLineAllPoint(archs: Array<LineArch> = LineArch.attaArch.get(this.attachment), line: GeoLine = this.attachment) : boolean {
- return archs.length !== 0 && archs.some(arch =>
- !isContainPoint(line, arch.linePoints[0]) ||
- !isContainPoint(line, arch.linePoints[1])
- )
- }
- // 获取线条内所有建筑,并且替换掉指定arch的points
- private getLineNewAll(points: [point, point] = this.linePoints, repArch = this) {
- let archs = [...LineArch.attaArch.get(this.attachment)]
- archs.splice(archs.indexOf(repArch), 1, { linePoints: points } as unknown as LineArch)
- return archs
- }
- // 检测是否合格通过
- qualified(points: [point, point] = this.linePoints, line: GeoLine = this.attachment) {
- return !(
- this.checkPointBorder(points[0], line) ||
- this.checkPointBorder(points[0], line) ||
- this.checkPoint(points[0], line) ||
- this.checkPoint(points[1], line) ||
- this.checkWidth(points)
- )
- }
- // 宿主线条点变化引起变化
- lineChange (point = this.attachment.points[0], move: point = point) : {line: GeoLine, points: [point, point]} {
- let {x, y} = move
- let index = this.attachment.points.findIndex(item => item === point);
- // 获取当前变化线条
- let line = { points: index === 0 ?
- [{x, y}, this.attachment.points[1]] : [this.attachment.points[0], {x, y}]
- } as GeoLine;
- let dis1 = lineDis({points: [line.points[index], this.linePoints[0]] })
- let [p11, p12] = getDisPointLinePoints(line, line.points[index], dis1)
- let point1 = lineDis({points: [p11, this.linePoints[0]]}) > lineDis({points: [p12, this.linePoints[0]]}) ? p12 : p11
- let dis2 = lineDis({points: [line.points[index], this.linePoints[1]] })
- let [p21, p22] = getDisPointLinePoints(line, line.points[index], dis2)
- let point2 = lineDis({points: [p21, this.linePoints[1]]}) > lineDis({points: [p22, this.linePoints[1]]}) ? p22 : p21
-
- // 让linepoint类检查一下
- let points = (
- lineDis({points: [this.linePoints[0], point1]}) < lineDis({points: [this.linePoints[0], point2]}) ?
- [point1, point2] : [point2, point1]
- ).map(
- (point) => {
- let p = LinePoint.prototype.getLineInsertPoint.call({...this.linePoints[0], line}, point)
- if (pointLineDis(this.attachment, p) > 0.1) {
- return lineDis({points: [this.attachment.points[0], p]}) < lineDis({points: [this.attachment.points[1], p]}) ?
- {x: this.attachment.points[0].x, y: this.attachment.points[0].y} :
- {x: this.attachment.points[1].x, y: this.attachment.points[1].y}
- } else {
- return p
- }
- }
- ) as [point, point]
- return { line, points }
- }
- // 建筑沿线点变化引起变化
- pointChange(point, {x, y}): [point, point] {
- let index = this.linePoints.findIndex(p => p === point)
- return index === 0 ?
- [{x, y}, this.linePoints[1]] : [this.linePoints[0], {x, y}]
- }
- lineChangeCheck(points, line, archs) {
- return this.qualified(points, line) && !this.checkLineAllPoint(archs, line) && !this.checkPointOverlapAttaArch(archs)
- }
- // 当变化时
- intercept(trgs: Array<any>, {x, y}, rets) {
- if (type.isUndefined(x) || type.isUndefined(y)) return true;
- let seftPointIndex, linePoint
- // 如果是线条而引起的变化
- if (linePoint = this.attachment.points.find(point => trgs.some(trg => trg === point))) {
- let {points, line} = this.lineChange(linePoint, {x, y})
- // 把所有沿线建筑改为最新值
- let arches: Array<LineArch> = trgs
- .filter(trg => trg instanceof LineArch && trg.attachment.id === this.attachment.id);
- arches = Array.from(new Set(arches))
- this.attachment.nextTick(() => {
- if (!this.attachment || !this.attachment.points) {
- return this.destroy()
- }
- let {points, line} = this.lineChange(linePoint, {x: linePoint.x, y: linePoint.y})
- points.forEach((point, i) => {
- if (point) {
- this.linePoints[i].x = point.x
- this.linePoints[i].y = point.y
- }
- })
- this.nextTick(() => {
- if (this.linePoints && this.linePoints.length) {
- if (lineDis({points: this.linePoints}) <= this.deleteWidth) {
- this.destroy()
- }
- }
- })
- })
- this.attachment.update()
- // return false
- return {__points: points}
- // return true
- // 如果是linePoint引起的变化
-
- } else if ( ~(seftPointIndex = trgs.findIndex(trg => this.linePoints.some(p => p === trg))) ) {
- // let ret = rets[seftPointIndex]
- // let points = this.pointChange(trgs[seftPointIndex], ret)
- // this.attachment.update()
- // return true
- // return !(
- // this.checkPointBorder(ret) ||
- // this.checkPoint(ret) ||
- // this.checkWidth(points) ||
- // this.checkPointOverlapAttaArch(this.getLineNewAll(points))
- // )
- }
- }
-
- dragEnd() {
- this.nextTick(() => {
- if (lineDis({points: this.linePoints}) <= this.deleteWidth) {
- this.destroy()
- }
- })
- }
- destroy() {
- let Archs = LineArch.attaArch.get(this.attachment)
- if (Archs) {
- Archs.splice(Archs.indexOf(this), 1)
- console.log(this.linePoints[0], this)
- this.linePoints[0] && this.linePoints[0].destroy && this.linePoints[0].destroy()
- this.linePoints[1] && this.linePoints[1].destroy && this.linePoints[1].destroy()
- this.attachment = null
- this.linePoints = null
- this.update = null
- super.destroy()
- this.attachment.update()
- }
- }
- }
- type LineArchTemp<T={}> = LineArch & T
- export type LineArchTs = ({ new <T={}, K = any>(data: T): LineArchTemp<T> }) & {
- attaArch: Map<Line, Array<LineArch>>
- }
- export type LineArchClass = LineArch
- export default LineArch as LineArchTs
|