774 lines
21 KiB
TypeScript
774 lines
21 KiB
TypeScript
import { PolylineHelper } from '../../common/LayoutEngine/PolylineHelper.js'
|
||
import type { Curve2d } from '../../common/base/CAD.js'
|
||
import { Arc2d, CADExt, Line2d, Point2d } from '../../common/base/CAD.js'
|
||
import { equal } from '../../common/base/MathComm.js'
|
||
import { PlaceSpace,PlaceBlock,TextureType } from '../../confClass.js'
|
||
|
||
/** 生成矩形空间的相关算法 */
|
||
export class SpacePlus
|
||
{
|
||
/** 纹路:0正文 1反纹 */
|
||
static texture :TextureType = 0 // = TextureType.NORMAL_TEXTURE // 正纹
|
||
|
||
/** 设置空间的方向,横向或竖向 */
|
||
static setSpaceStyle(block: PlaceBlock)
|
||
{
|
||
|
||
if (block.texture == TextureType.NORMAL_TEXTURE) // 正纹
|
||
{
|
||
this.texture = 0
|
||
}
|
||
else if (block.texture == TextureType.REVERSE_TEXTURE) // 反纹
|
||
{
|
||
this.texture = 1
|
||
}
|
||
else // 可翻转
|
||
{
|
||
if (block.cutWidth < block.cutLength)
|
||
{
|
||
this.texture = 0
|
||
}
|
||
else
|
||
{
|
||
this.texture = 1
|
||
}
|
||
}
|
||
}
|
||
|
||
/** 复制轮廓 */
|
||
static copyBorder(curves: Curve2d[]): Curve2d[]
|
||
{
|
||
const newCurves: Curve2d[] = []
|
||
for (let i = 0; i < curves.length; i++)
|
||
{
|
||
const curve = curves[i]
|
||
const sp = curve.StartPoint
|
||
const ep = curve.EndPoint
|
||
if (curve instanceof Arc2d)
|
||
{
|
||
const arc = new Arc2d(new Point2d(sp.m_X, sp.m_Y), new Point2d(ep.m_X, ep.m_Y), curve.Bul)
|
||
newCurves.push(arc)
|
||
}
|
||
else
|
||
{
|
||
// 后面会修改line里头的起点终点,所以必须重新初始化, 确保不能影响原来的轮廓 border .
|
||
const newLine = new Line2d(new Point2d(sp.m_X, sp.m_Y), new Point2d(ep.m_X, ep.m_Y))
|
||
newCurves.push(newLine)
|
||
}
|
||
}
|
||
return newCurves
|
||
}
|
||
|
||
/** 从轮廓中分析空间 */
|
||
static borderToSpace(orgcurves: Curve2d[])
|
||
{
|
||
const curves = this.copyBorder(orgcurves)
|
||
// 1.新建线段列表 不影响源数据
|
||
// 弧线转成 直线
|
||
const lines: Line2d[] = []
|
||
for (let i = 0; i < curves.length;)
|
||
{
|
||
const curve = curves[i]
|
||
const sp = curve.StartPoint
|
||
const ep = curve.EndPoint
|
||
if (curve instanceof Arc2d)
|
||
{
|
||
const len = Math.abs(curve.m_Radius * curve.m_AllAngle) // 圆弧长度
|
||
|
||
if (len > 200) // 圆弧长大于 200 则拆分
|
||
{
|
||
const count = Math.ceil(len / 100)
|
||
const newArcs = CADExt.SplitArc(curve, count)
|
||
curves.splice(i, 1)
|
||
for (let j = newArcs.length - 1; j >= 0; j--)
|
||
{
|
||
curves.splice(i, 0, newArcs[j])
|
||
}
|
||
continue
|
||
}
|
||
else // 圆弧转换 直线
|
||
{
|
||
if (curve.Bul == 0)
|
||
{
|
||
curve.Parse()
|
||
}
|
||
const newLine = new Line2d(new Point2d(sp.m_X, sp.m_Y), new Point2d(ep.m_X, ep.m_Y))
|
||
// 外凸 直接转
|
||
if (curve.Bul >= 0)
|
||
{
|
||
newLine.canotSplit = true // 不能拆分
|
||
lines.push(newLine)
|
||
}
|
||
else // 内凹 算要算一下 弧形外接 矩形面积
|
||
{
|
||
const pts:any[] = []
|
||
pts.push({ x: curve.StartPoint.m_X, y: curve.StartPoint.m_Y, bul: curve.Bul })
|
||
pts.push({ x: curve.EndPoint.m_X, y: curve.EndPoint.m_Y, bul: 0 })
|
||
const pl = PolylineHelper.create(pts)
|
||
const box = pl.BoundingBox
|
||
this.setDirect(newLine)
|
||
const fx = newLine.fx
|
||
const newPoints :any[] = []
|
||
newPoints.push({ x: sp.m_X, y: sp.m_Y })
|
||
switch (fx)
|
||
{
|
||
case 0:
|
||
newPoints.push({ x: box.min.x, y: box.min.y })
|
||
newPoints.push({ x: box.min.x, y: box.max.y })
|
||
newPoints.push({ x: box.max.x, y: box.max.y })
|
||
newPoints.push({ x: box.max.x, y: box.min.y })
|
||
break
|
||
case 1:
|
||
newPoints.push({ x: box.max.x, y: box.min.y })
|
||
newPoints.push({ x: box.min.x, y: box.min.y })
|
||
newPoints.push({ x: box.min.x, y: box.max.y })
|
||
newPoints.push({ x: box.max.x, y: box.max.y })
|
||
break
|
||
case 2:
|
||
newPoints.push({ x: box.max.x, y: box.max.y })
|
||
newPoints.push({ x: box.max.x, y: box.min.y })
|
||
newPoints.push({ x: box.min.x, y: box.min.y })
|
||
newPoints.push({ x: box.min.x, y: box.max.y })
|
||
break
|
||
case 3:
|
||
newPoints.push({ x: box.min.x, y: box.max.y })
|
||
newPoints.push({ x: box.max.x, y: box.max.y })
|
||
newPoints.push({ x: box.max.x, y: box.min.y })
|
||
newPoints.push({ x: box.min.x, y: box.min.y })
|
||
break
|
||
case 4:
|
||
newPoints.push({ x: box.min.x, y: sp.m_Y })
|
||
newPoints.push({ x: box.min.x, y: box.max.y })
|
||
newPoints.push({ x: ep.m_X, y: box.max.y })
|
||
break
|
||
case 5:
|
||
newPoints.push({ x: sp.m_X, y: box.min.y })
|
||
newPoints.push({ x: box.min.x, y: box.min.y })
|
||
newPoints.push({ x: box.min.x, y: ep.m_Y })
|
||
break
|
||
case 6:
|
||
newPoints.push({ x: box.max.x, y: sp.m_Y })
|
||
newPoints.push({ x: box.max.x, y: box.min.y })
|
||
newPoints.push({ x: ep.m_X, y: box.min.y })
|
||
break
|
||
case 7:
|
||
newPoints.push({ x: sp.m_X, y: box.max.y })
|
||
newPoints.push({ x: box.max.x, y: box.max.y })
|
||
newPoints.push({ x: box.max.x, y: ep.m_Y })
|
||
break
|
||
default:
|
||
}
|
||
newPoints.push({ x: ep.m_X, y: ep.m_Y })
|
||
for (let n = 0; n < newPoints.length - 1; n++)
|
||
{
|
||
const m = n + 1
|
||
const newLine = new Line2d(new Point2d(newPoints[n].x, newPoints[n].y), new Point2d(newPoints[m].x, newPoints[m].y))
|
||
lines.push(newLine)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// 后面会修改line里头的起点终点,所以必须重新初始化 ,确保不能影响原来的轮廓 border .
|
||
const newLine = new Line2d(new Point2d(sp.m_X, sp.m_Y), new Point2d(ep.m_X, ep.m_Y))
|
||
lines.push(newLine)
|
||
}
|
||
|
||
i++
|
||
}
|
||
|
||
// 2 轮廓需要够大
|
||
let minX = 1000
|
||
let minY = 1000
|
||
let maxX = -1000
|
||
let maxY = -1000
|
||
for (const line of lines)
|
||
{
|
||
if (line.StartPoint.m_X < minX)
|
||
minX = line.StartPoint.m_X
|
||
if (line.StartPoint.m_X > maxX)
|
||
maxX = line.StartPoint.m_X
|
||
if (line.StartPoint.m_Y < minY)
|
||
minY = line.StartPoint.m_Y
|
||
if (line.StartPoint.m_Y > maxY)
|
||
maxY = line.StartPoint.m_Y
|
||
if (line.EndPoint.m_X < minX)
|
||
minX = line.EndPoint.m_X
|
||
if (line.EndPoint.m_X > maxX)
|
||
maxX = line.EndPoint.m_X
|
||
if (line.EndPoint.m_Y < minY)
|
||
minY = line.EndPoint.m_Y
|
||
if (line.EndPoint.m_Y > maxY)
|
||
maxY = line.EndPoint.m_Y
|
||
}
|
||
if (maxX - minX < 50)
|
||
return // 太小了,就不要分析
|
||
if (maxY - minY < 50)
|
||
return
|
||
if ((maxX - minX) * (maxY - minY) < 10000)
|
||
return []
|
||
|
||
// 3.将长斜线 ,转成 多段
|
||
|
||
for (let i = 0; i < lines.length;)
|
||
{
|
||
const line = lines[i]
|
||
if (this.isXL(line))
|
||
{
|
||
if (line.canotSplit) // 不能拆分
|
||
{
|
||
|
||
}
|
||
else
|
||
{
|
||
const sp = line.StartPoint
|
||
const ep = line.EndPoint
|
||
if (line.m_Length > 300 && Math.abs(sp.m_X - ep.m_X) > 50 && Math.abs(sp.m_X - ep.m_X) > 50) // 够长,截断
|
||
{
|
||
const cx = (line.StartPoint.m_X + line.EndPoint.m_X) / 2
|
||
const cy = (line.StartPoint.m_Y + line.EndPoint.m_Y) / 2
|
||
|
||
line.EndPoint = new Point2d(cx, cy)
|
||
line.Parse()
|
||
const newLine = new Line2d(new Point2d(cx, cy), new Point2d(ep.m_X, ep.m_Y))
|
||
lines.splice(i + 1, 0, newLine)
|
||
continue
|
||
}
|
||
}
|
||
}
|
||
i++
|
||
}
|
||
|
||
// 3.斜线 -> 横平竖直
|
||
for (let i = 0; i < lines.length; i++)
|
||
{
|
||
this.turnToLine(lines, i)
|
||
}
|
||
|
||
// 6.将line 标识方向
|
||
for (let i = lines.length - 1; i >= 0; i--)
|
||
{
|
||
if (this.setDirect(lines[i]) == -1)
|
||
lines.splice(i, 1)
|
||
}
|
||
|
||
const tmpSpaces = []
|
||
// 7.开始分析空间
|
||
this.parseSpace(lines, tmpSpaces)
|
||
// 8.合并空间
|
||
this.mergeSpaces(tmpSpaces)
|
||
// 9 生成
|
||
const spaces: PlaceSpace[] = []
|
||
for (const tmp of tmpSpaces)
|
||
{
|
||
const space = PlaceSpace.create(tmp.x1, tmp.y1, tmp.x2, tmp.y2)
|
||
spaces.push(space)
|
||
}
|
||
return spaces
|
||
}
|
||
|
||
/** 闭合(逆时针)的线段内分析空间 */
|
||
private static parseSpace(lines: Line2d[], spaces: any[])
|
||
{
|
||
const childs = this.resetLines(lines)
|
||
if (childs.length > 1) // 分叉
|
||
{
|
||
for (const child of childs)
|
||
{
|
||
this.parseSpace(child, spaces)
|
||
}
|
||
return
|
||
}
|
||
|
||
// 没有分支,才开始真正计算
|
||
lines = childs[0]
|
||
if (lines.length < 4)
|
||
return // 至少有4条
|
||
|
||
/**
|
||
* 思路:在线段里头 找到一段连续且成矩形的3条直线,即可组成一个矩形
|
||
* 然后:去掉(或缩短)这3条直线,再重新找
|
||
*/
|
||
let space
|
||
for (let i = 0; i < lines.length; i++)
|
||
{
|
||
space = this.createSpace(lines, i)
|
||
if (space)
|
||
break
|
||
}
|
||
// 没找到任何空间, 直接退出
|
||
if (!space)
|
||
return
|
||
|
||
// 找到了,继续往下找
|
||
spaces.push(space)
|
||
this.parseSpace(lines, spaces)
|
||
}
|
||
|
||
/** 分析空间大的保留,小的合并 */
|
||
static mergeSpaces(spaces: any[])
|
||
{
|
||
const minW = 50 // 空间最小宽度
|
||
const minL = 200
|
||
const avgW = 60
|
||
|
||
// 不损失 合并空间
|
||
for (let i = 0; i < spaces.length;)
|
||
{
|
||
const space1 = spaces[i]
|
||
let hasMerge = false // 是否合并一个空间
|
||
for (let j = i + 1; j < spaces.length;)
|
||
{
|
||
const space2 = spaces[j]
|
||
hasMerge = mergeSpace(space1, space2) // space2 是否被合并
|
||
if (hasMerge)
|
||
{
|
||
spaces.splice(j, 1)
|
||
break
|
||
}
|
||
j++
|
||
}
|
||
if (hasMerge)
|
||
break
|
||
i++
|
||
}
|
||
// 小空间 委屈合并
|
||
for (let i = 0; i < spaces.length;)
|
||
{
|
||
const space1 = spaces[i]
|
||
if (big(space1) == false) // 小空间,找别人合并
|
||
{
|
||
mergeSpace2(i)
|
||
spaces.splice(i, 1)// 删除小空间
|
||
continue
|
||
}
|
||
i++
|
||
}
|
||
|
||
/** 空间 大否 */
|
||
function big(space)
|
||
{
|
||
let w = space.x2 - space.x1
|
||
if (w < minW)
|
||
return false
|
||
let l = space.y2 - space.y1
|
||
if (l < minW)
|
||
return false
|
||
|
||
if (w > l)
|
||
[w, l] = [l, w]
|
||
|
||
if (w >= minW && l >= minL)
|
||
return true
|
||
if (w >= avgW && l >= avgW)
|
||
return true
|
||
|
||
return false
|
||
}
|
||
|
||
/** 不损失 合并空间 */
|
||
function mergeSpace(sp1, sp2)
|
||
{
|
||
// 上下 宽一样
|
||
if (equal(sp1.x1, sp2.x1) && equal(sp1.x2, sp2.x2) && (equal(sp1.y2, sp2.y1) || equal(sp2.y2, sp1.y1)))
|
||
{
|
||
sp1.y1 = Math.min(sp1.y1, sp2.y1)
|
||
sp1.y2 = Math.max(sp1.y2, sp2.y2)
|
||
return true
|
||
}
|
||
// 左右 高一样
|
||
if (equal(sp1.y1, sp2.y1) && equal(sp1.y2, sp2.y2) && (equal(sp1.x2, sp2.x1) || equal(sp2.x2, sp1.x1)))
|
||
{
|
||
sp1.x1 = Math.min(sp1.x1, sp2.x1)
|
||
sp1.x2 = Math.max(sp1.x2, sp2.x2)
|
||
return true
|
||
}
|
||
|
||
return false
|
||
}
|
||
|
||
/** 损失 合并空间,四周找一个空间,合并后效果最好的 */
|
||
function mergeSpace2(index: number)
|
||
{
|
||
const cur = spaces[index]
|
||
const canSpaces = []
|
||
for (let i = 0; i < spaces.length; i++)
|
||
{
|
||
if (i == index)
|
||
continue
|
||
const oth = spaces[i]
|
||
let x1, y1, x2, y2
|
||
// 右边的
|
||
if (equal(cur.x2, oth.x1) && cur.y1 < oth.y2 && cur.y2 > oth.y1)
|
||
{
|
||
x1 = cur.x1
|
||
y1 = Math.max(cur.y1, oth.y1)
|
||
x2 = oth.x2
|
||
y2 = Math.min(cur.y2, oth.y2)
|
||
}
|
||
// 左边的
|
||
else if (equal(cur.x1, oth.x2) && cur.y1 < oth.y2 && cur.y2 > oth.y1)
|
||
{
|
||
x1 = oth.x1
|
||
y1 = Math.max(cur.y1, oth.y1)
|
||
x2 = cur.x2
|
||
y2 = Math.min(cur.y2, oth.y2)
|
||
}
|
||
// 下边的
|
||
else if (equal(cur.y1, oth.y2) && cur.x1 < oth.x2 && cur.x2 > oth.x1)
|
||
{
|
||
x1 = Math.max(cur.x1, oth.x1)
|
||
y1 = oth.y1
|
||
x2 = Math.min(cur.x2, oth.x2)
|
||
y2 = cur.y2
|
||
}
|
||
// 上边的
|
||
else if (equal(cur.y2, oth.y1) && cur.x1 < oth.x2 && cur.x2 > oth.x1)
|
||
{
|
||
x1 = Math.max(cur.x1, oth.x1)
|
||
y1 = cur.y1
|
||
x2 = Math.min(cur.x2, oth.x2)
|
||
y2 = oth.y2
|
||
}
|
||
else
|
||
{
|
||
continue
|
||
}
|
||
|
||
// oth 原来面积
|
||
const size_org = (oth.x2 - oth.x1) * (oth.y2 - oth.y1)
|
||
const size_new = (x2 - x1) * (y2 - y1)
|
||
|
||
const size_plus = size_new - size_org
|
||
if (size_plus < 0)
|
||
continue // 合并 面积更小,就不要合并
|
||
|
||
const space = { x1, y1, x2, y2 }
|
||
canSpaces.push({ size_plus, space, i })
|
||
}
|
||
if (canSpaces.length == 0)
|
||
return // 没有可以合并的
|
||
|
||
// 按增大面积 排序
|
||
canSpaces.sort((a, b) => b.size_plus - a.size_plus)
|
||
// 取效果最好的。
|
||
const newSpace = canSpaces[0].space
|
||
// 替换 oth ,
|
||
spaces.splice(canSpaces[0].i, 1, newSpace)
|
||
}
|
||
}
|
||
|
||
/** 整理多段线 */
|
||
private static resetLines(lines: Line2d[]): Line2d[][]
|
||
{
|
||
for (let i = 0; i < lines.length;)
|
||
{
|
||
const lp = lines[i]
|
||
let n = i + 1
|
||
if (n == lines.length)
|
||
n = 0
|
||
const ln = lines[n]
|
||
if (lp.m_Length < 0.001) // 太短了,移除
|
||
{
|
||
lines.splice(i, 1)
|
||
i = 0
|
||
continue
|
||
}
|
||
|
||
if (lp.fx == ln.fx) // 同向,
|
||
{
|
||
lp.EndPoint = ln.EndPoint
|
||
lp.Parse()
|
||
lines.splice(n, 1)
|
||
i = 0
|
||
continue
|
||
}
|
||
if (lp.fx % 2 == ln.fx % 2) // 反向
|
||
{
|
||
lp.EndPoint = ln.EndPoint
|
||
lp.Parse()
|
||
this.setDirect(lp)
|
||
lines.splice(n, 1)
|
||
if ((lp.fx == 0 && lp.EndPoint.m_X < lp.StartPoint.m_X)
|
||
|| (lp.fx == 1 && lp.EndPoint.m_Y < lp.StartPoint.m_Y)
|
||
|| (lp.fx == 2 && lp.EndPoint.m_X > lp.StartPoint.m_X)
|
||
|| (lp.fx == 3 && lp.EndPoint.m_Y > lp.StartPoint.m_Y)) // 这很奇葩,该空间 不能分析,直接清除所有线段
|
||
{
|
||
lines.splice(0, lines.length)
|
||
return
|
||
}
|
||
i = 0
|
||
continue
|
||
}
|
||
i++
|
||
}
|
||
|
||
// 判断 有向下的线,与向上的线 重叠。 则要分开; 类似 与 管 的下面 2个口
|
||
let line0: Line2d
|
||
let line1: Line2d
|
||
let i = -1
|
||
let j = -1
|
||
let x = 0
|
||
for (i = 0; i < lines.length; i++)
|
||
{
|
||
if (lines[i].fx == 3)
|
||
{
|
||
x = lines[i].StartPoint.m_X
|
||
j = lines.findIndex(t => t.fx == 1 && t.StartPoint.m_X == x)
|
||
if (j >= 0)
|
||
{
|
||
line0 = lines[i]
|
||
line1 = lines[j]
|
||
break
|
||
}
|
||
}
|
||
}
|
||
|
||
if (!line0 || !line1)
|
||
return [lines] // 没找到
|
||
|
||
const rt = []
|
||
const si = Math.min(i, j)
|
||
const ei = Math.max(i, j)
|
||
|
||
const lines_s: Line2d[] = []
|
||
const lines_x: Line2d[] = []
|
||
for (let i = si + 1; i <= ei - 1; i++)
|
||
{
|
||
lines_s.push(lines[i])
|
||
}
|
||
for (let i = ei + 1; i <= lines.length + si - 1; i++)
|
||
{
|
||
const ri = i % lines.length
|
||
lines_x.push(lines[ri])
|
||
}
|
||
|
||
if (lines_s.length >= 3)
|
||
{
|
||
const pe = lines_s[lines_s.length - 1].EndPoint
|
||
const ps = lines_s[0].StartPoint
|
||
const newLine = new Line2d(new Point2d(pe.m_X, pe.m_Y), new Point2d(ps.m_X, ps.m_Y))
|
||
this.setDirect(newLine)
|
||
lines_s.push(newLine)
|
||
rt.push(lines_s)
|
||
}
|
||
if (lines_x.length >= 3)
|
||
{
|
||
const pe = lines_x[lines_x.length - 1].EndPoint
|
||
const ps = lines_x[0].StartPoint
|
||
const newLine = new Line2d(new Point2d(pe.m_X, pe.m_Y), new Point2d(ps.m_X, ps.m_Y))
|
||
this.setDirect(newLine)
|
||
lines_x.push(newLine)
|
||
rt.push(lines_x)
|
||
}
|
||
|
||
return rt
|
||
}
|
||
|
||
/** line如果是斜线,转换成直线 */
|
||
private static turnToLine(lines: Line2d[], i: number)
|
||
{
|
||
if (!this.isXL(lines[i]))
|
||
return
|
||
|
||
const sp = lines[i].StartPoint
|
||
const ep = lines[i].EndPoint
|
||
const sx = sp.m_X
|
||
const sy = sp.m_Y
|
||
const ex = ep.m_X
|
||
const ey = ep.m_Y
|
||
let cx = 0
|
||
let cy = 0
|
||
// ↖ 换成 ←↑
|
||
if (ex < sx && ey > sy)
|
||
{
|
||
cx = ex
|
||
cy = sy
|
||
}
|
||
else if (ex < sx && ey < sy) // ↙ 换成 ←↓
|
||
{
|
||
cx = sx
|
||
cy = ey
|
||
}
|
||
else if (ex > sx && ey < sy) // ↘ 换成 →↓
|
||
{
|
||
cx = ex
|
||
cy = sy
|
||
}
|
||
else if (ex > sx && ey > sy) // ↗ 换成 →↑
|
||
{
|
||
cx = sx
|
||
cy = ey
|
||
}
|
||
if (cx == 0 && cy == 0)
|
||
return
|
||
|
||
const line1 = new Line2d(new Point2d(sx, sy), new Point2d(cx, cy))
|
||
const line2 = new Line2d(new Point2d(cx, cy), new Point2d(ex, ey))
|
||
lines.splice(i, 1, line1, line2)
|
||
}
|
||
|
||
/** 线段设置方向 */
|
||
private static setDirect(line: Line2d)
|
||
{
|
||
let fx = -1 // 向右 0,向上 1,向左 2,向下 3 ,右上 4,左上5,左下6,右下 7
|
||
if (line.EndPoint.m_X > line.StartPoint.m_X && equal(line.EndPoint.m_Y, line.StartPoint.m_Y))
|
||
{
|
||
fx = 0
|
||
}
|
||
else if (line.EndPoint.m_X < line.StartPoint.m_X && equal(line.EndPoint.m_Y, line.StartPoint.m_Y))
|
||
{
|
||
fx = 2
|
||
}
|
||
else if (line.EndPoint.m_Y > line.StartPoint.m_Y && equal(line.EndPoint.m_X, line.StartPoint.m_X))
|
||
{
|
||
fx = 1
|
||
}
|
||
else if (line.EndPoint.m_Y < line.StartPoint.m_Y && equal(line.EndPoint.m_X, line.StartPoint.m_X))
|
||
{
|
||
fx = 3
|
||
}
|
||
else if (line.EndPoint.m_X > line.StartPoint.m_X && line.EndPoint.m_Y > line.StartPoint.m_Y)
|
||
{
|
||
fx = 4
|
||
}
|
||
else if (line.EndPoint.m_X < line.StartPoint.m_X && line.EndPoint.m_Y > line.StartPoint.m_Y)
|
||
{
|
||
fx = 5
|
||
}
|
||
else if (line.EndPoint.m_X < line.StartPoint.m_X && line.EndPoint.m_Y < line.StartPoint.m_Y)
|
||
{
|
||
fx = 6
|
||
}
|
||
else if (line.EndPoint.m_X > line.StartPoint.m_X && line.EndPoint.m_Y < line.StartPoint.m_Y)
|
||
{
|
||
fx = 7
|
||
}
|
||
line.fx = fx
|
||
return fx
|
||
}
|
||
|
||
/** 斜线 */
|
||
private static isXL(line: Curve2d) { return !equal(line.StartPoint.m_X, line.EndPoint.m_X) && !equal(line.StartPoint.m_Y, line.EndPoint.m_Y) }
|
||
|
||
/** 3条线,方向持续, 组成空间 */
|
||
private static createSpace(lines: Line2d[], i: number)
|
||
{
|
||
let j = i + 1
|
||
let n = i + 2
|
||
if (j >= lines.length)
|
||
j = j - lines.length
|
||
if (n >= lines.length)
|
||
n = n - lines.length
|
||
|
||
const line1 = lines[i]
|
||
const line2 = lines[j]
|
||
const line3 = lines[n]
|
||
|
||
const fx1 = line1.fx
|
||
if (line2.fx != (fx1 + 1) % 4)
|
||
return
|
||
if (line3.fx != (fx1 + 2) % 4)
|
||
return
|
||
|
||
// 安装板的纹路,进行开始计算空间,横的,还是竖的
|
||
if (fx1 % 2 != this.texture)
|
||
return
|
||
|
||
let x1, y1, x2, y2
|
||
let sp, ep
|
||
if (fx1 == 0)
|
||
{
|
||
x1 = Math.max(line1.StartPoint.m_X, line3.EndPoint.m_X)
|
||
y1 = line2.StartPoint.m_Y
|
||
x2 = line2.EndPoint.m_X
|
||
y2 = line2.EndPoint.m_Y
|
||
|
||
sp = new Point2d(x1, y1)
|
||
ep = new Point2d(x1, y2)
|
||
}
|
||
else if (fx1 == 1)
|
||
{
|
||
x1 = line2.EndPoint.m_X
|
||
y1 = Math.max(line1.StartPoint.m_Y, line3.EndPoint.m_Y)
|
||
x2 = line2.StartPoint.m_X
|
||
y2 = line2.StartPoint.m_Y
|
||
sp = new Point2d(x2, y1)
|
||
ep = new Point2d(x1, y1)
|
||
}
|
||
else if (fx1 == 2)
|
||
{
|
||
x1 = line2.EndPoint.m_X
|
||
y1 = line2.EndPoint.m_Y
|
||
x2 = Math.min(line1.StartPoint.m_X, line3.EndPoint.m_X)
|
||
y2 = line2.StartPoint.m_Y
|
||
|
||
sp = new Point2d(x2, y2)
|
||
ep = new Point2d(x2, y1)
|
||
}
|
||
else if (fx1 == 3)
|
||
{
|
||
x1 = line2.StartPoint.m_X
|
||
y1 = line2.StartPoint.m_Y
|
||
x2 = line2.EndPoint.m_X
|
||
y2 = Math.min(line1.StartPoint.m_Y, line3.EndPoint.m_Y)
|
||
|
||
sp = new Point2d(x1, y2)
|
||
ep = new Point2d(x2, y2)
|
||
}
|
||
else
|
||
{
|
||
return
|
||
}
|
||
|
||
// 在新空间内,不能出现其他的线段,
|
||
for (let o = 0; o < lines.length; o++)
|
||
{
|
||
if (o == i || o == j || o == n)
|
||
continue
|
||
const oth = lines[o]
|
||
if (oth.EndPoint.m_X > x1 + 0.001 && oth.EndPoint.m_X < x2 - 0.001 && oth.EndPoint.m_Y > y1 + 0.001 && oth.EndPoint.m_Y < y2 - 0.001)
|
||
return
|
||
}
|
||
|
||
// 缩短line1, line3
|
||
line1.EndPoint = sp
|
||
line1.Parse()
|
||
this.setDirect(line1)
|
||
line3.StartPoint = ep
|
||
line3.Parse()
|
||
this.setDirect(line3)
|
||
// 删除 line2 ,添加 新连接线
|
||
const newline = new Line2d(new Point2d(sp.m_X, sp.m_Y), new Point2d(ep.m_X, ep.m_Y))
|
||
this.setDirect(newline)
|
||
|
||
lines.splice(j, 1, newline)
|
||
const space = { x1, y1, x2, y2 }
|
||
return space
|
||
}
|
||
|
||
/** 反转 */
|
||
static reverseCurves(curves: Curve2d[]): Curve2d[]
|
||
{
|
||
const newCurs: Curve2d[] = []
|
||
for (let i = curves.length - 1; i >= 0; i--)
|
||
{
|
||
const cur = curves[i]
|
||
const sp = cur.StartPoint
|
||
const ep = cur.EndPoint
|
||
if (cur instanceof Arc2d)
|
||
{
|
||
const newArc = new Arc2d(ep, sp, -cur.Bul)
|
||
newCurs.push(newArc)
|
||
}
|
||
else
|
||
{
|
||
const newline = new Line2d(ep, sp)
|
||
newCurs.push(newline)
|
||
}
|
||
}
|
||
return newCurs
|
||
}
|
||
}
|