用三次贝塞尔拟合矩形
拟合矩形比较简单,只需要四个锚点,因为是个闭合曲线,所以每个锚点都有两个控制点,而且控制点和锚点的坐标一样。
那么在鼠标Mousedown时记录当前pos作为矩形的第一个锚点(左上角),在mousemove的时候记录当前pos作为第三个锚点(右下角),在mouseup时计算出所有点的坐标,加入pathlist即可。 具体计算过程如下:
export function getRectNodes(node: Node){
let {posX,posY,ctrPosY,ctrPosX} = node;
let nodes = [];
nodes[0] = { posX:posX, posY:posY, ctrPosX:posX, ctrPosY:posY, ctr2PosX:posX, ctr2PosY:posY }
nodes[1] = { posX:ctrPosX, posY:posY, ctrPosX: ctrPosX, ctrPosY: posY, ctr2PosX:ctrPosX, ctr2PosY:posY }
nodes[2] = { posX:ctrPosX, posY:ctrPosY, ctrPosX:ctrPosX, ctrPosY:ctrPosY, ctr2PosX:ctrPosX, ctr2PosY:ctrPosY }
nodes[3] = { posX:posX, posY:ctrPosY, ctrPosX: posX, ctrPosY: ctrPosY, ctr2PosX:posX, ctr2PosY:ctrPosY }
return nodes;
}
用三次贝塞尔拟合圆形
用三次贝塞尔拟合圆形也需要四个锚点,每个锚点需要两个控制点。这里的关键点是锚点到控制点的距离,这个距离会影响曲线的弯曲程度。
通过查阅资料(具体证明)知道这个距离是半径*0.551915024494。
那么在mousedown的时候记录pos作为圆心的位置,mousemove的pos和圆形的pos计算出半径,mousedown的时候计算四个锚点和相应控制点的坐标,然后加入pathlist。
具体计算过程:
export function getCircleNodes(node: Node){
const C = 0.552284749831;
let {posX,posY,ctrPosY,ctrPosX} = node;
let radius = Math.sqrt((posX-ctrPosX)*(posX-ctrPosX) + (posY-ctrPosY)* (posY-ctrPosY));
let h = C * radius;
let nodes = [];
nodes[0] = {
posX:posX,
posY:posY + radius,
ctrPosX:posX + h,
ctrPosY:posY + radius,
ctr2PosX: posX - h,
ctr2PosY: posY + radius,
}
nodes[1] = {
posX:posX + radius,
posY:posY,
ctrPosX: posX + radius,
ctrPosY: posY + h,
ctr2PosX:posX + radius,
ctr2PosY:posY - h
}
nodes[2] = {
posX:posX,
posY:posY - radius,
ctrPosX: posX + h,
ctrPosY: posY - radius,
ctr2PosX:posX - h,
ctr2PosY:posY - radius
}
nodes[3] = {
posX:posX - radius,
posY:posY,
ctrPosX: posX - radius,
ctrPosY: posY - h,
ctr2PosX:posX - radius,
ctr2PosY:posY + h
}
return nodes;
}