直角多边形添加圆角
来源:互联网 发布:2017年8月进出口数据 编辑:程序博客网 时间:2024/04/28 06:01
最近工作的时候遇到需要对矩形增加圆角的功能,网上学习了一下添加圆角的方式,先顺利完成了。后来又遇到图档中含有非矩形直角多边形,原来的方式不行了,头疼。仔细研究了一下圆角的添加情况,增加了对圆角中心点的位置判断,顺利解决。希望给有需要的人一些帮助。注:直角多边形定义:任意相交两边互相垂直的封闭平面图形。
添加圆角做法:先在某边上取与端点(P)距离为圆角半径的一点,以此点(R)为原点,旋转此端点90度(正负与圆角方向有关),可得到此端点处的圆角中心(O)。再以圆角中心为中心,旋转R点,可得圆角上的所有点。
难点:圆角方向不定,需自行判断。另外一个小点是: 已知一点,以此点为中心,旋转另一点,得到新的点的坐标。
解决思路:通过三点,判断中间点处的圆角的位置。取多边形相交两边,以起点到终点分别定为点1,点2,点3。分析可知,线12旋转至线13的角度与绕R点旋转P点得到O点时的方向一致,而产生圆角时的角度也与此方向也相关。问题的关键在于如何判断O点的位置。一开始考虑计算线13与线12之间的角度,没直接方案,计算与X轴角度之后再进行加减,顺时针输入四点坐标时是OK的,但逆时针输入四点坐标,发现有一个角出问题,圆角方向有误,Debug发现Atan函数返回的是-pi 到 pi之间的值,因此超过了180度之后,再进行加减就不对了。再观察分析,点O必处于点1,2,3围成的三角形内。故选择暴力破解法,生成两个O点,判断与点3之间的间距,进而确定正确的O点。最终实现了无论顺时针还是逆时针,顺序输入直角多边形各个端点的坐标,即可生成对应的圆角多边形的坐标。
具体C#代码如下:
public struct pointF { public double x; public double y;};
//对直角多边形(大于4边)进行增加圆角功能。直角多边形定义:任意相连两边角度为90度。
private void AddCircleAngleToRect(pointF[] pointInput,int nCount, double dCircleR, ref double[,] PointArray, ref int iPointNum)
{
for (int i = 0; i < nCount; i++)
{
//连续三点坐标判断中间点处的圆角圆心
//根据判断线 13与线12的角度来判断点2处的圆角圆心的位置
double dMidRotation = 0.0;
double dLen12 = TwoPointLen(pointInput[(i + 1) % nCount], pointInput[i]);
if (dLen12 < dCircleR)
{
MessageBox.Show("错误,圆角半径过大");
return false;
}
pointF pCircleCenter = new pointF();
pointF tempPointOnLine12 = new pointF();
tempPointOnLine12.x = pointInput[(i + 1) % nCount].x * (dLen12 - dCircleR) / dLen12 - pointInput[i].x * (-dCircleR) / dLen12;
tempPointOnLine12.y = pointInput[(i + 1) % nCount].y * (dLen12 - dCircleR) / dLen12 - pointInput[i].y * (-dCircleR) / dLen12;
pointF temPoint1 = Rotate(pointInput[(i + 1) % nCount], tempPointOnLine12, 0.5 * Math.PI);
pointF temPoint2 = Rotate(pointInput[(i + 1) % nCount], tempPointOnLine12, -0.5 * Math.PI);
double dLen3t1 = TwoPointLen(pointInput[(i + 2) % nCount], temPoint1);
double dLen3t2 = TwoPointLen(pointInput[(i + 2) % nCount], temPoint2);
if (dLen3t1 < dLen3t2)
{
pCircleCenter = temPoint1;
dMidRotation = 90;
}
else
{
pCircleCenter = temPoint2;
dMidRotation = -90;
}
//画圆角
for (int n = 0; n * 15 <= 90; n++)
{
pointF pt = Rotate(tempPointOnLine12, pCircleCenter, (n * 15) * (dMidRotation / 90) * Math.PI / 180);
PointArray[iPointNum, 0] = pt.x;
PointArray[iPointNum, 1] = pt.y;
//对应数组的长度
iPointNum += 1;}
}
PointArray[iPointNum, 0] = PointArray[0, 0];
PointArray[iPointNum, 1] = PointArray[0, 1];
//iPointNum 做为个数。
iPointNum += 1;
return true;
}
//返回以pBasciPoint为原点,旋转pFixpoint点 zeta 弧度后得到的点的坐标
private pointF Rotate(pointF pFixpoint, pointF pBasciPoint, double zeta)
{
pointF pFixResult = new pointF();
pFixResult.x = (pFixpoint.x - pBasciPoint.x) * Math.Cos(zeta) - (pFixpoint.y - pBasciPoint.y) * Math.Sin(zeta) + pBasciPoint.x;
pFixResult.y = (pFixpoint.x - pBasciPoint.x) * Math.Sin(zeta) + (pFixpoint.y - pBasciPoint.y) * Math.Cos(zeta) + pBasciPoint.y;
return pFixResult;
}
//返回两点间距离
private double TwoPointLen(pointF pPoint1, pointF pPoint2)
{
double dLen = Math.Sqrt((pPoint2.y - pPoint1.y) * (pPoint2.y - pPoint1.y) + (pPoint2.x - pPoint1.x) * (pPoint2.x - pPoint1.x));
return dLen;
}
Good luck
- 直角多边形添加圆角
- 直角图片进行圆角处理
- ios 直角和圆角 并存
- android上面圆角,下面直角 ImageView
- Bootstrap 按钮圆角改成直角
- Xcode9模拟器圆角切换成直角
- Imageview上边圆角,下边直角
- 画圆直角
- 平面直角坐标系---点坐标与多边形位置判断
- Android实现button一边圆角一边直角
- Android 自定义上面圆角下面直角的ImageView
- bitmap分别设置四角,圆角还是直角,自定义
- Android实现button一边圆角一边直角
- 安卓自定义上面圆角下面直角的RoundCornerImageView
- 设置Button按钮上面圆角下面直角
- 把 Firefox 的圆角标签,变成直角标签
- Android实现Imageview上面圆角下面直角效果
- iOS 将控件设置为一边圆角一边直角
- SICP 练习1.38 寻找e的值
- Binary Tree Level Order Traversal II
- 使用spring-jdbc访问数据库
- 使用Socket进行设备间点对点连接传输数据
- json数据格式学习
- 直角多边形添加圆角
- leetcode-Java-234. Palindrome Linked List.java
- logback实现每个线程一个独立的日志文件
- Android官方开发文档Training系列课程中文版:连接无线设备之网络服务搜索功能
- 继承Thread类的线程实现方法
- php学习第二天----基础语法4
- Android-调用系统照相机
- 多线程同步辅助类——CountDownLatch
- 取消eclipse代码自动换行