【SDU Chart Team - Core】点的更新回调 & 基于回调传播图像更新

更新回调

点的更新回调

使用回调机制,允许设置回调函数:

void Point2D::on_update(const std::function<void(const double &, const double &, const double &, const double &)> callback) {
     _callback = callback;
}
void Point2D::on_update() {
     _callback = [](const double &lx, const double &ly, const double &x, const double &y){};
}

每次进行更新时,检查与当前值的差是否大于 1 e − 6 1e^{-6} 1e6,否则认为未被更新;然后调用回调函数:

if (!(_eq(_x, last_x) && _eq(_y, last_y))) _callback(last_x, last_y, _x, _y);

基于回调传播图像更新

主动点 & 从动点

关键点的移动,引发了一个几何学的主从动点问题。主从动点的概念来源于一次更新。

  • 主动点:在一次更新中不受其他点的约束而位置发生改变。
  • 从动点:再一次更新受其他点的约束而位置发生改变。

在图形绘制中,用户移动的点一定是主动点,此时被引发变化的点一定是从动点。

将主从动点的关系扩展到多次更新,那么主从动点的关系在每次更新中都有体现。在前一次更新中作为从动点的点,成为下一次更新的主动点;如此循环往复,形成了多条更新链;按照更新的次数划分层数,令主动点指向从动点,可以得到一个有向无环图;如果使用状态机模型,则可能存在环。
更新过程DAG
更新过程状态机

称上述过程为更新传播。

注意:更新的前提是位置发生改变,如果约束并没有使某点发生改变,则该点并不是从动点。

合法更新域

并不是所有更新位置都是合法的。例如矩形的顶边中点:
合法更新域
它的合法更新域为 x x x于其相等的直线。但是更本质的描述是,它必须是左上于右上点连接成的线段点中点。

每次更新传播中的约束,应当保证从动点移动到它的合法更新域。若不合法,则应当回溯。

另外,在首次更新前,可以通过认为限制,例如对用户的输入进行预处理,从而保证首次更新中的主动点在合法更新域中。

基于回调传播更新

矩形更新例子
  • 回调函数

    分为两个部分。

    • 四个顶点

      在回调函数中首先更新相邻的顶点,再由相邻的顶点计算邻边的中点。以左上角顶点LT为例:

      LB->setX(nx); RT->setY(ny);
      *L = (*LT + *LB) * 0.5;
      *T = (*LT + *RT) * 0.5;
      
    • 四个边的中点

      在回调函数中直接更新相邻的顶点。以顶边中点为例:

      LT->setY(ny), RT->setY(ny);
      
  • 更新过程模拟

    假设对LT作更新,则经过如下更新传播过程后得到结果:
    传播过程

  • 收敛性

    只要约束是稳定关系,就能保证收敛。

  • 非收敛情形

    如果是非稳定关系,可以通过引入迭代次数,限制迭代次数从而强制收敛;对于迭代中在稳定状态附近震荡的情形,可以引入精度,当当前状态满足一定精度时停止。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值