使用场景
可视化 超椭圆系数 对 曲线 的作用
autojs版本
缘由
小米200万的logo, 200万的曲线有多圆, 知乎大神给了公式
知乎提问: 如何看待网友称小米网页上 logo 只改了一行代码,logo 就从方变圆?是真的吗?
超椭圆百科
超椭圆(superellipse)也称为Lamé曲线,是一种类似于椭圆的封闭曲线,保留了椭圆的长轴、短轴、对称性的特点。
超椭圆(superellipse)也称为Lamé曲线,是在笛卡儿坐标系下满足以下方程式的点的集合:
其中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), }); }
声明
部分内容来自网络