metaball公式_Metaball变形球效果实现

效果图

Metaball

一 .求出圆的外公切线

image.png

两个圆心之间的距离,也就是两点之间的距离

const distanceBetweenCenter = Math.sqrt(Math.pow(c1.cx - c2.cx, 2) + Math.pow(c1.cy - c2.cy, 2));

计算直线C1C2与水平线的角度

const angleBetweenCenters = Math.atan2(c2.cy - c1.cy, c2.cx - c1.cx);

角P2C1C2可以根据公式求出

const spread = Math.acos((c1.radius - c2.radius) / distanceBetweenCenter);

那么就可以算出四个点的角度,注意,按照上面的图,angleBetweenCenters计算出来的是负数,spread是正数,

所以angle1就是p1点的角度,angle2就是p2点的角度,以此类推。

const angle1 = angleBetweenCenters + spread;

const angle2 = angleBetweenCenters - spread;

const angle3 = angleBetweenCenters + spread;

const angle4 = angleBetweenCenters - spread;

根据圆的半径与坐标,就可以求出切点坐标

const p1 = getVector(c1.cx, c1.cy, angle1, c1.radius);

const p2 = getVector(c1.cx, c1.cy, angle2, c1.radius);

const p3 = getVector(c2.cx, c2.cy, angle3, c2.radius);

const p4 = getVector(c2.cx, c2.cy, angle4, c2.radius);

function getVector(cx, cy, a, r) {

return {x: cx + r * Math.cos(a), y: cy + r * Math.sin(a)};

}

二.偏移切点位置

如果在这样的切点做变形球效果,肯定不好看,我们给出一个系数v=0.5,让切点稍微一点偏移,也就是向两圆直接偏移,注意,下面的代码和上面的角度计算不一样,不如 角P4C2C1 =Math.PI - spread,这个角度乘上v,是不是变得更小了,然后Math.PI - 角P4C2C1 也就变得更大了,这样P4就会向圆C1偏移了。

const angle1 = angleBetweenCenters + spread * v;

const angle2 = angleBetweenCenters - spread * v;

const angle3 = angleBetweenCenters + Math.PI - (Math.PI - spread) * v;

const angle4 = angleBetweenCenters - (Math.PI -(Math.PI - spread) * v);

image.png

计算控制点

这里需要用贝塞尔曲线了,而且还是三阶的,这就需要二个控制点

image.png

先计算两个圆圆心的距离totalRadius,想要随着圆的位置变化,控制点也需要变,给出d2比例参数

这里的HALF_PI是因为切点方向。

const d2 = (dist(p1.x, p1.y, p3.x, p3.y) / totalRadius);

const r1 = c1.radius * d2;

const r2 = c2.radius * d2;

const h1 = this.getVector(p1.x, p1.y, angle1 - HALF_PI, r1);

const h2 = this.getVector(p2.x, p2.y, angle2 + HALF_PI, r1);

const h3 = this.getVector(p3.x, p3.y, angle3 + HALF_PI, r2);

const h4 = this.getVector(p4.x, p4.y, angle4 - HALF_PI, r2);

三.画曲线

现在我们有切点有控制点,可以画曲线了,

ctx.beginPath();

ctx.strokeStyle = c2.color;

ctx.m

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值