使用场景
可视化 超椭圆系数 对 曲线 的作用
效果展示
超椭圆
autojs版本
缘由
小米200万的logo, 200万的曲线有多圆, 知乎大神给了公式
知乎提问: 如何看待网友称小米网页上 logo 只改了一行代码,logo 就从方变圆?是真的吗?
超椭圆百科
超椭圆(superellipse)也称为Lamé曲线,是一种类似于椭圆的封闭曲线,保留了椭圆的长轴、短轴、对称性的特点。
超椭圆(superellipse)也称为Lamé曲线,是在笛卡儿坐标系下满足以下方程式的点的集合:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-m7BuAiX4-1617618897853)(https://bkimg.cdn.bcebos.com/formula/9793f98ce86404f9271f96d1210b1b83.svg)]
其中n、a及b为正数。
上述方程式的解会是一个在−a≤x≤+a及−b≤y≤+b长方形内的封闭曲线,参数a及b称为曲线的半直径(semi-diameters)。常见的超椭圆有星形线。
预备知识
代码讲解
1. 布局
canvas + text + seekbar
ui.layout(
<vertical gravity="center">
<canvas id="board" w="230dp" h="230dp"></canvas>
<text textSize="26sp" textStyle="bold" gravity="center" textColor="#1abc9c">
作者: 牙叔
</text>
<horizontal w="*" h="wrap_content" gravity="center" margin="3">
<text textSize="30sp" textStyle="bold" gravity="center">
N:
</text>
<text id="hyperellipseN" textSize="30sp" textStyle="bold" gravity="center">
3
</text>
...
</horizontal>
<horizontal margin="3">
<text textSize="30sp" h="50dp" textStyle="bold">
N
</text>
<seekbar id="seekbarN" w="*" h="50dp" max="100" />
</horizontal>
...
</vertical>
);
2. 初始化参数
let mPaint = new Paint();
let color = "#ff6900";
color = colors.parseColor(color);
mPaint.setColor(color);
mPaint.setStrokeWidth(10); // 设置圆环的宽度
mPaint.setAntiAlias(true); // 消除锯齿
mPaint.setStyle(Paint.Style.STROKE); // 设置空心
board = ui.board;
let mPath = new Path();
let deviation;
let multiple;
let n = 30;
let a = 1;
let b = 10;
let count = 1;
3. 设置滑块的监听事件
ui.seekbarN.setOnSeekBarChangeListener(seekbarNListenerN);
ui.seekbarA.setOnSeekBarChangeListener(seekbarAListenerA);
ui.seekbarB.setOnSeekBarChangeListener(seekbarBListenerB);
ui.seekbarCount.setOnSeekBarChangeListener(seekbarBListenerCount);
4. 画超椭圆
function draw() {
deviation = board.getWidth() / 2;
multiple = board.getWidth() / 2 - 20;
let oMultiple = multiple;
board.on("draw", function (canvas) {
canvas.drawARGB(255, 127, 127, 127);
for (let i = 0; i < count; i++) {
画超椭圆(canvas, n, a, b, deviation, multiple);
multiple = multiple - 30;
}
multiple = oMultiple;
});
}
5. 超椭圆坐标计算
for (let x = -1; x < 1; x = x + step) {
y = Math.pow(1 - Math.pow(Math.abs(x / a), n), 1 / n) * b;
points.push({
x: Math.round(x * multiple + deviation),
y: Math.round(y * multiple + deviation),
});
}
for (let x = 1; x > -1; x = x - step) {
y = -Math.pow(1 - Math.pow(Math.abs(x / a), n), 1 / n) * b;
points.push({
x: Math.round(x * multiple + deviation),
y: Math.round(y * multiple + deviation),
});
}
完整源码
声明
部分内容来自网络
微信公众号 AutoJsPro教程
添加作者微信, 邀你入群交流
QQ群
747748653