Cocos 2d-x与Bezier的圆角 [英] Rounded Corners Rect in Cocos 2d-x with Bezier

查看:194
本文介绍了Cocos 2d-x与Bezier的圆角的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以使用DrawNode对象绘制具有圆角的Rect?
我认为使用Bezier曲线是可能的,但我做了一些尝试,我认为我无法处理它。



查看API I'我发现只有这两个函数:

drawQuadBezier (const Vec2& origin,const Vec2& control,const Vec2& destination,unsigned int segments,const Color4F& color)


$ b

drawCubicBezier (const Vec2& origin,const Vec2& control1,const Vec2& control2,const Vec2& destination,unsigned int segments,const Color4F& color)






[回答后修改]



Cocos2dx 中回答,也许有人觉得这很有用:



(如果您不需要高精度)

  auto MagicConst = 0.552; 
auto position = 150;
auto R = 50;

Vec2 TopLeft = Vec2(position,position + R * 2);
Vec2 TopRight = Vec2(位置+ R * 2,位置+ R * 2);
Vec2 BottomRight = Vec2(position + R * 2,position);
Vec2 BottomLeft = Vec2(position,position);

Vec2 originTL = Vec2(TopLeft.x,TopLeft.y - R);
Vec2 originTR = Vec2(TopRight.x - R,TopRight.y);
Vec2 originBR = Vec2(BottomRight.x - R,BottomRight.y);
Vec2 originBL = Vec2(BottomLeft.x,BottomLeft.y + R);

Vec2 control1TL = Vec2(TopLeft.x,(int)(TopLeft.y - R *(1 - MagicConst)));
Vec2 control1TR = Vec2((int)(TopRight.x - R *(1 - MagicConst)),TopRight.y);
Vec2 control1BR = Vec2((int)(BottomRight.x - R *(1 - MagicConst)),BottomRight.y);
Vec2 control1BL = Vec2(BottomLeft.x,(int)(BottomLeft.y + R *(1 - MagicConst)));

Vec2 control2TL = Vec2((int)(TopLeft.x + R *(1 - MagicConst)),TopLeft.y);
Vec2 control2TR = Vec2(TopRight.x,(int)(TopRight.y - R *(1 - MagicConst)));
Vec2 control2BR = Vec2(BottomRight.x,(int)(BottomRight.y + R *(1 - MagicConst)));
Vec2 control2BL = Vec2((int)(BottomLeft.x + R *(1-MagicConst)),BottomLeft.y);

Vec2 destinationTL = Vec2(TopLeft.x + R,TopLeft.y);
Vec2 destinationTR = Vec2(TopRight.x,TopRight.y - R);
Vec2 destinationBR = Vec2(BottomRight.x,BottomRight.y + R);
Vec2 destinationBL = Vec2(BottomLeft.x + R,BottomLeft.y);

auto roundCorner = DrawNode :: create();
roundCorner-> drawCubicBezier(originTL,control1TL,control2TL,destinationTL,10,Color4F :: RED);
roundCorner-> drawCubicBezier(originTR,control1TR,control2TR,destinationTR,10,Color4F :: GREEN);
roundCorner-> drawCubicBezier(originBR,control1BR,control2BR,destinationBR,10,Color4F :: YELLOW);
roundCorner-> drawCubicBezier(originBL,control1BL,control2BL,destinationBL,10,Color4F :: WHITE);
addChild(roundCorner);

这会产生: http://i.stack.imgur.com/mdEOM.png



现在您可以更改 MagicConst 可以随心所欲地四舍五入。



例如 MagicConst = 0.9 http://i.stack.imgur.com/9V5cr.png



那是我想要的结果! ;)(谢谢@Mbo)



(我现在还不能发布嵌入图片):P


可以计算三次贝塞尔曲线,该曲线近似于四分之一圆以产生圆角。

轴的左上角示例 - 对齐矩形(点TopLeft)和弧半径R:



编辑:更改了一些 - / +符号

  MagicConst = 0.552 
Bezier.origin.X = ToplLeft.X
Bezier.origin.Y = ToplLeft.Y + R
Bezier.control1.X = ToplLeft.X
Bezier.control1.Y = ToplLeft.Y + R *(1-MagicConst)
Bezier.control2.X = ToplLeft.X + R *(1- MagicConst)
Bezier.control2.Y = ToplLeft.Y
Bezier.destination.X = ToplLeft.X + R
Bezier.destination.Y = ToplLeft.Y

关于MagicConstant



您可以轻松找到类似的symm其他角落的坐标坐标。
我没有考虑极端短矩形边缘的情况(<2 * R)


Is it possible to draw a Rect with rounded corners using a DrawNode object? I think that something is possible using Bezier curves, but I have made some tries and I think I can't handle it.

Looking at API I've found only these 2 functions:

drawQuadBezier (const Vec2 &origin, const Vec2 &control, const Vec2 &destination, unsigned int segments, const Color4F &color)

drawCubicBezier (const Vec2 &origin, const Vec2 &control1, const Vec2 &control2, const Vec2 &destination, unsigned int segments, const Color4F &color)


[Modified after answer]

I have applied the answer in Cocos2dx, maybe somebody find this useful:

(just done some casting to int if you don't need high precision)

auto MagicConst = 0.552;
auto position = 150;
auto R = 50;

Vec2 TopLeft = Vec2(position, position + R * 2);
Vec2 TopRight = Vec2(position + R * 2, position + R * 2);
Vec2 BottomRight = Vec2(position + R * 2, position);
Vec2 BottomLeft = Vec2(position, position);

Vec2 originTL = Vec2(TopLeft.x, TopLeft.y - R);
Vec2 originTR = Vec2(TopRight.x - R, TopRight.y);
Vec2 originBR = Vec2(BottomRight.x - R, BottomRight.y);
Vec2 originBL = Vec2(BottomLeft.x, BottomLeft.y + R);

Vec2 control1TL = Vec2(TopLeft.x, (int) (TopLeft.y - R * (1 - MagicConst)));
Vec2 control1TR = Vec2((int) (TopRight.x - R * (1 - MagicConst)), TopRight.y);
Vec2 control1BR = Vec2((int) (BottomRight.x - R * (1 - MagicConst)), BottomRight.y);
Vec2 control1BL = Vec2(BottomLeft.x, (int) (BottomLeft.y + R * (1 - MagicConst)));

Vec2 control2TL = Vec2((int) (TopLeft.x + R * (1 - MagicConst)), TopLeft.y);
Vec2 control2TR = Vec2(TopRight.x, (int) (TopRight.y - R * (1 - MagicConst)));
Vec2 control2BR = Vec2(BottomRight.x, (int) (BottomRight.y + R * (1 - MagicConst)));
Vec2 control2BL = Vec2((int) (BottomLeft.x + R * (1 - MagicConst)), BottomLeft.y);

Vec2 destinationTL = Vec2(TopLeft.x + R, TopLeft.y);
Vec2 destinationTR = Vec2(TopRight.x, TopRight.y - R);
Vec2 destinationBR = Vec2(BottomRight.x, BottomRight.y + R);
Vec2 destinationBL = Vec2(BottomLeft.x + R, BottomLeft.y);

auto roundCorner = DrawNode::create();
roundCorner->drawCubicBezier(originTL, control1TL, control2TL, destinationTL, 10, Color4F::RED);
roundCorner->drawCubicBezier(originTR, control1TR, control2TR, destinationTR, 10, Color4F::GREEN);
roundCorner->drawCubicBezier(originBR, control1BR, control2BR, destinationBR, 10, Color4F::YELLOW);
roundCorner->drawCubicBezier(originBL, control1BL, control2BL, destinationBL, 10, Color4F::WHITE);
addChild(roundCorner);

This will produce: http://i.stack.imgur.com/mdEOM.png

Now you can change MagicConst to round the corners as you want.

For example with MagicConst = 0.9: http://i.stack.imgur.com/9V5cr.png

That is the result I wanted! ;) (thank you @Mbo)

(I can't post embedded image yet) :P

解决方案

It is possible to calculate cubic Bezier curve that approximates a quarter of circle to make round corner.
Example for top left corner of axis-aligned rectangle (point TopLeft) and arc radius R:

Edit: Changed some -/+ signs

MagicConst = 0.552
Bezier.origin.X = ToplLeft.X
Bezier.origin.Y = ToplLeft.Y + R
Bezier.control1.X = ToplLeft.X
Bezier.control1.Y = ToplLeft.Y + R * (1-MagicConst)
Bezier.control2.X = ToplLeft.X + R * (1-MagicConst)
Bezier.control2.Y = ToplLeft.Y
Bezier.destination.X = ToplLeft.X + R
Bezier.destination.Y = ToplLeft.Y

about MagicConstant

You can easily find similar symmetric coordinates for other corners. I did not consider case of extreme short rectangle edges (<2*R)

这篇关于Cocos 2d-x与Bezier的圆角的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆