# Android 任意多边形以任意条边画平分线切割图形算法

• 实现需求分析
• 实现方案解决
• 代码实现

## 实现需求分析

• 一般式Ax+By+c=0
• 斜截式 Kx+c=0

A=Y2-Y1;
B=X1-X2;
C=Y1*X2-Y2*X1;

 /**
* 计算线段的直线方程
*
* @param landPoint1
* @param landPoint2
* @return
*/
public static LineSlope calculateSignleSlope(LandPoint landPoint1, LandPoint landPoint2) {
double A = landPoint2.getyPoint() - landPoint1.getyPoint();
double B = landPoint1.getxPoint() - landPoint2.getxPoint();
double C = landPoint1.getyPoint() * landPoint2.getxPoint() - landPoint1.getxPoint() * landPoint2.getyPoint();
System.out.println("A=" + A + "B=" + B + "C==" + C);
return new LineSlope(A, B, C, landPoint1, landPoint2);
}

/**
* 获取平行线移动分割方向
*
* @param xielv0
* @param xielv1
* @param xielv2
* @param distance
* @return
*/
public static int getDirection(LineSlope xielv0, LineSlope xielv1, LineSlope xielv2, double distance) {
BigDecimal A = new BigDecimal(xielv1.getA()).multiply(new BigDecimal(xielv1.getA()));
BigDecimal B = new BigDecimal(xielv1.getB()).multiply(new BigDecimal(xielv1.getB()));
BigDecimal add = A.add(B);
double c = new BigDecimal(xielv1.getC()).add(new BigDecimal(distance).multiply(new BigDecimal(1)).multiply(new BigDecimal(StrictMath.sqrt(add.doubleValue())))).doubleValue();
double xPoint = (new BigDecimal(xielv2.getC()).multiply(new BigDecimal(xielv1.getB())).subtract(new BigDecimal(c).multiply(new BigDecimal(xielv2.getB()))))
.divide((new BigDecimal(xielv1.getA()).multiply(new BigDecimal(xielv2.getB())).subtract(new BigDecimal(xielv1.getB()).multiply(new BigDecimal(xielv2.getA())))), 20, BigDecimal.ROUND_HALF_DOWN).doubleValue();
double yPoint = (new BigDecimal(xielv1.getA()).multiply(new BigDecimal(xielv2.getC())).subtract(new BigDecimal(c).multiply(new BigDecimal(xielv2.getA()))))
.divide((new BigDecimal(xielv1.getB()).multiply(new BigDecimal(xielv2.getA())).subtract(new BigDecimal(xielv1.getA()).multiply(new BigDecimal(xielv2.getB())))), 20, BigDecimal.ROUND_HALF_DOWN).doubleValue();
LandPoint landPoint = new LandPoint(xPoint, yPoint);
double a = xielv2.getPoint1().getxPoint() > xielv2.getPoint2().getxPoint() ? xielv2.getPoint1().getxPoint() : xielv2.getPoint2().getxPoint();
double a1 = xielv2.getPoint1().getxPoint() < xielv2.getPoint2().getxPoint() ? xielv2.getPoint1().getxPoint() : xielv2.getPoint2().getxPoint();
double b = xielv2.getPoint1().getyPoint() > xielv2.getPoint2().getyPoint() ? xielv2.getPoint1().getyPoint() : xielv2.getPoint2().getyPoint();
double b1 = xielv2.getPoint1().getyPoint() < xielv2.getPoint2().getyPoint() ? xielv2.getPoint1().getyPoint() : xielv2.getPoint2().getyPoint();
if (landPoint.getxPoint() <= a && landPoint.getxPoint() >= a1 && landPoint.getyPoint() <= b && landPoint.getyPoint() >= b1) {
System.out.println(landPoint.getxPoint() + "__Point__" + landPoint.getyPoint());
return 1;
} else {
double c1 = new BigDecimal(xielv1.getC()).add(new BigDecimal(distance).multiply(new BigDecimal(1)).multiply(new BigDecimal(StrictMath.sqrt(new BigDecimal(xielv1.getA()).multiply(new BigDecimal(xielv1.getA())).add(new BigDecimal(xielv1.getB()).multiply(new BigDecimal(xielv1.getB()))).doubleValue())))).doubleValue();
double xPoint1 = (new BigDecimal(xielv0.getC()).multiply(new BigDecimal(xielv1.getB())).subtract(new BigDecimal(c1).multiply(new BigDecimal(xielv0.getB()))))
.divide((new BigDecimal(xielv1.getA()).multiply(new BigDecimal(xielv0.getB())).subtract(new BigDecimal(xielv1.getB()).multiply(new BigDecimal(xielv0.getA())))), 20, BigDecimal.ROUND_HALF_DOWN).doubleValue();
double yPoint1 = (new BigDecimal(xielv1.getA()).multiply(new BigDecimal(xielv0.getC())).subtract(new BigDecimal(c1).multiply(new BigDecimal(xielv0.getA()))))
.divide((new BigDecimal(xielv1.getB()).multiply(new BigDecimal(xielv0.getA())).subtract(new BigDecimal(xielv1.getA()).multiply(new BigDecimal(xielv0.getB())))), 20, BigDecimal.ROUND_HALF_DOWN).doubleValue();
LandPoint landPoint1 = new LandPoint(xPoint1, yPoint1);
double a11 = xielv0.getPoint1().getxPoint() > xielv0.getPoint2().getxPoint() ? xielv0.getPoint1().getxPoint() : xielv0.getPoint2().getxPoint();
double a12 = xielv0.getPoint1().getxPoint() < xielv0.getPoint2().getxPoint() ? xielv0.getPoint1().getxPoint() : xielv0.getPoint2().getxPoint();
double b11 = xielv0.getPoint1().getyPoint() > xielv0.getPoint2().getyPoint() ? xielv0.getPoint1().getyPoint() : xielv0.getPoint2().getyPoint();
double b12 = xielv0.getPoint1().getyPoint() < xielv0.getPoint2().getyPoint() ? xielv0.getPoint1().getyPoint() : xielv0.getPoint2().getyPoint();
if (landPoint1.getxPoint() <= a11 && landPoint1.getxPoint() >= a12 && landPoint1.getyPoint() <= b11 && landPoint1.getyPoint() >= b12) {
System.out.println(landPoint1.getxPoint() + "__Point__" + landPoint1.getyPoint());
return 1;
} else {
return 0;
}
}
}


 /**
* 获取所有的平行线端点
*
* @param position
* @param xielvs
* @param distance
* @return
*/
public static ArrayList<LandPointArrayList> getAllLinePoints(int position, ArrayList<LineSlope> xielvs, double distance) {
ArrayList<LandPointArrayList> landPointArrayLists = new ArrayList<>();
int direction;
final double D = xielvs.get(position).getC();
double C = xielvs.get(position).getC();
int j = 1;
boolean isComputeing = true;
if (position == xielvs.size() - 1) {
direction = getDirection(xielvs.get(position - 1), xielvs.get(position), xielvs.get(0), distance);
} else if (position == 0) {
direction = getDirection(xielvs.get(xielvs.size() - 1), xielvs.get(position), xielvs.get(position + 1), distance);
} else {
direction = getDirection(xielvs.get(position - 1), xielvs.get(position), xielvs.get(position + 1), distance);
}
LineSlope xielvOld = new LineSlope(xielvs.get(position).getA(), xielvs.get(position).getB(), xielvs.get(position).getC(), xielvs.get(position).getPoint1(), xielvs.get(position).getPoint2());
xielvs.remove(position);
while (isComputeing) {
LandPointArrayList landPointArrayList = new LandPointArrayList();
switch (direction) {
case 0:
C = new BigDecimal(D).subtract(new BigDecimal(distance).multiply(new BigDecimal(j)).multiply(new BigDecimal(StrictMath.sqrt(new BigDecimal(xielvOld.getA()).multiply(new BigDecimal(xielvOld.getA())).add(new BigDecimal(xielvOld.getB()).multiply(new BigDecimal(xielvOld.getB()))).doubleValue())))).doubleValue();
break;
case 1:
C = new BigDecimal(D).add(new BigDecimal(distance).multiply(new BigDecimal(j)).multiply(new BigDecimal(StrictMath.sqrt(new BigDecimal(xielvOld.getA()).multiply(new BigDecimal(xielvOld.getA())).add(new BigDecimal(xielvOld.getB()).multiply(new BigDecimal(xielvOld.getB()))).doubleValue())))).doubleValue();
break;
}
xielvOld.setC(C);
for (int i = 0; i < xielvs.size(); i++) {
double xPoint = (new BigDecimal(xielvs.get(i).getC()).multiply(new BigDecimal(xielvOld.getB())).subtract(new BigDecimal(xielvOld.getC()).multiply(new BigDecimal(xielvs.get(i).getB()))))
.divide((new BigDecimal(xielvOld.getA()).multiply(new BigDecimal(xielvs.get(i).getB())).subtract(new BigDecimal(xielvOld.getB()).multiply(new BigDecimal(xielvs.get(i).getA())))), 20, BigDecimal.ROUND_HALF_DOWN).doubleValue();
double yPoint = (new BigDecimal(xielvOld.getA()).multiply(new BigDecimal(xielvs.get(i).getC())).subtract(new BigDecimal(xielvOld.getC()).multiply(new BigDecimal(xielvs.get(i).getA()))))
.divide((new BigDecimal(xielvOld.getB()).multiply(new BigDecimal(xielvs.get(i).getA())).subtract(new BigDecimal(xielvOld.getA()).multiply(new BigDecimal(xielvs.get(i).getB())))), 20, BigDecimal.ROUND_HALF_DOWN).doubleValue();
LandPoint landPoint = new LandPoint(xPoint, yPoint);
double a = xielvs.get(i).getPoint1().getxPoint() > xielvs.get(i).getPoint2().getxPoint() ? xielvs.get(i).getPoint1().getxPoint() : xielvs.get(i).getPoint2().getxPoint();
double a1 = xielvs.get(i).getPoint1().getxPoint() < xielvs.get(i).getPoint2().getxPoint() ? xielvs.get(i).getPoint1().getxPoint() : xielvs.get(i).getPoint2().getxPoint();
double b = xielvs.get(i).getPoint1().getyPoint() > xielvs.get(i).getPoint2().getyPoint() ? xielvs.get(i).getPoint1().getyPoint() : xielvs.get(i).getPoint2().getyPoint();
double b1 = xielvs.get(i).getPoint1().getyPoint() < xielvs.get(i).getPoint2().getyPoint() ? xielvs.get(i).getPoint1().getyPoint() : xielvs.get(i).getPoint2().getyPoint();
if (landPoint.getxPoint() <= a && landPoint.getxPoint() >= a1 && landPoint.getyPoint() <= b && landPoint.getyPoint() >= b1) {
System.out.println(landPoint.getxPoint() + "__Point__" + landPoint.getyPoint());
if (landPointArrayList.getLandPointStart() == null) {
landPointArrayList.setLandPointStart(landPoint);
} else {
landPointArrayList.setLandPointEnd(landPoint);
}

}

}
if (landPointArrayList.getLandPointStart() == null || landPointArrayList.getLandPointEnd() == null) {
isComputeing = false;
} else {
landPointArrayLists.add(landPointArrayList);
}
j = j + 1;
}
return landPointArrayLists;
}


   /**
* @param landPointArrayLists 平行线的两个端点
* @param lineLong            箭头长度
* @return 箭头点
*/
public ArrayList<ArrowPoint> getArrow(ArrayList<LandPointArrayList> landPointArrayLists, int lineLong) {
double number = StrictMath.sqrt(3);
ArrayList<ArrowPoint> arrowList = new ArrayList();
boolean right = true;
for (LandPointArrayList landPointArrayList : landPointArrayLists) {
double centerPointLineX = (new BigDecimal(landPointArrayList.getLandPointStart().getxPoint()).add(new BigDecimal(landPointArrayList.getLandPointEnd().getxPoint()))).divide(new BigDecimal("2")).doubleValue();
double centerPointLineY = (new BigDecimal(landPointArrayList.getLandPointStart().getyPoint()).add(new BigDecimal(landPointArrayList.getLandPointEnd().getyPoint()))).divide(new BigDecimal("2")).doubleValue();
double A = landPointArrayList.getLandPointEnd().getyPoint() - landPointArrayList.getLandPointStart().getyPoint();
double B = landPointArrayList.getLandPointStart().getxPoint() - landPointArrayList.getLandPointEnd().getxPoint();
double C = landPointArrayList.getLandPointStart().getyPoint() * landPointArrayList.getLandPointEnd().getxPoint() - landPointArrayList.getLandPointStart().getxPoint() * landPointArrayList.getLandPointEnd().getyPoint();
double v = Math.atan(-new BigDecimal(A).divide(new BigDecimal(B), 20, BigDecimal.ROUND_HALF_DOWN).doubleValue()) * 180 / Math.PI;
double K = Math.tan((v + 30) * Math.PI / 180);
double cnum = new BigDecimal(centerPointLineY).subtract(new BigDecimal(centerPointLineX).multiply(new BigDecimal(K))).doubleValue();
BigDecimal add = new BigDecimal("1").add(new BigDecimal(K).multiply(new BigDecimal(K)));
BigDecimal bigDecimal = new BigDecimal(StrictMath.sqrt(add.doubleValue()));
double arrowX1 = new BigDecimal(centerPointLineX).subtract(new BigDecimal(lineLong).divide(bigDecimal, 20, BigDecimal.ROUND_HALF_DOWN)).doubleValue();
double arrowX2 = new BigDecimal(centerPointLineX).add(new BigDecimal(lineLong).divide(new BigDecimal(StrictMath.sqrt(new BigDecimal("1").add(new BigDecimal(K).multiply(new BigDecimal(K))).doubleValue())), 20, BigDecimal.ROUND_HALF_DOWN)).doubleValue();
double arrowY1 = new BigDecimal(K).multiply(new BigDecimal(arrowX1)).add(new BigDecimal(cnum)).doubleValue();
double arrowY2 = new BigDecimal(K).multiply(new BigDecimal(arrowX2)).add(new BigDecimal(cnum)).doubleValue();

double K2 = Math.tan((v - 30) * Math.PI / 180);
double cnum2 = new BigDecimal(centerPointLineY).subtract(new BigDecimal(centerPointLineX).multiply(new BigDecimal(K2))).doubleValue();
double arrowX21 = new BigDecimal(centerPointLineX).subtract(new BigDecimal(lineLong).divide(new BigDecimal(StrictMath.sqrt(new BigDecimal("1").add(new BigDecimal(K2).multiply(new BigDecimal(K2))).doubleValue())), 20, BigDecimal.ROUND_HALF_DOWN)).doubleValue();
double arrowX22 = new BigDecimal(centerPointLineX).add(new BigDecimal(lineLong).divide(new BigDecimal(StrictMath.sqrt(new BigDecimal("1").add(new BigDecimal(K2).multiply(new BigDecimal(K2))).doubleValue())), 20, BigDecimal.ROUND_HALF_DOWN)).doubleValue();
double arrowY21 = new BigDecimal(K2).multiply(new BigDecimal(arrowX21)).add(new BigDecimal(cnum2)).doubleValue();
double arrowY22 = new BigDecimal(K2).multiply(new BigDecimal(arrowX22)).add(new BigDecimal(cnum2)).doubleValue();

Log.e("aaaaa", "cnum" + cnum + "cnum2" + cnum2 + "---" + "arrowX1" + arrowX1 + "arrowY1" + arrowY1 + "---" + "arrowX2" + arrowX2 + "arrowY2" + arrowY2 + "---" + "arrowX21" + arrowX21 + "arrowY21" + arrowY21 + "---" + "arrowX22" + arrowX22 + "arrowY22" + arrowY22);
double maxX1 = Math.max(arrowX1, arrowX2);
double maxX2 = Math.max(arrowX21, arrowX22);
double maxY1 = new BigDecimal(K).multiply(new BigDecimal(maxX1)).add(new BigDecimal(cnum)).doubleValue();
double maxY2 = new BigDecimal(K2).multiply(new BigDecimal(maxX2)).add(new BigDecimal(cnum2)).doubleValue();

double minX1 = Math.min(arrowX1, arrowX2);
double minX2 = Math.min(arrowX21, arrowX22);
double minY1 = new BigDecimal(K).multiply(new BigDecimal(minX1)).add(new BigDecimal(cnum)).doubleValue();
double minY2 = new BigDecimal(K2).multiply(new BigDecimal(minX2)).add(new BigDecimal(cnum2)).doubleValue();
LandPoint startPoint;
LandPoint endPoint;
LandPoint maxEndPoint;
LandPoint maxStartPoint;
LandPoint minStartPoint;
LandPoint minEndPoint;

double divide = new BigDecimal(-A).divide(new BigDecimal(B), 20, BigDecimal.ROUND_HALF_DOWN).doubleValue();

double maxY3 = Math.max(arrowY1, arrowY2);
double maxY4 = Math.max(arrowY21, arrowY22);

if (arrowY1 > arrowY2) {
maxStartPoint = new LandPoint(arrowX1, arrowY1);
minStartPoint = new LandPoint(arrowX2, arrowY2);
} else {
maxStartPoint = new LandPoint(arrowX2, arrowY2);
minStartPoint = new LandPoint(arrowX1, arrowY1);
}

if (arrowY21 > arrowY22) {
maxEndPoint = new LandPoint(arrowX21, arrowY21);
minEndPoint = new LandPoint(arrowX22, arrowY22);
} else {
maxEndPoint = new LandPoint(arrowX22, arrowY22);
minEndPoint = new LandPoint(arrowX21, arrowY21);
}

if (divide < -number || divide > number) {
if (right) {
startPoint = maxStartPoint;
endPoint = maxEndPoint;
right = false;
} else {
startPoint = minStartPoint;
endPoint = minEndPoint;
right = true;
}
} else {
if (right) {
startPoint = new LandPoint(maxX1, maxY1);
endPoint = new LandPoint(maxX2, maxY2);
right = false;
} else {
startPoint = new LandPoint(minX1, minY1);
endPoint = new LandPoint(minX2, minY2);
right = true;
}

}
arrowList.add(new ArrowPoint(startPoint, new LandPoint(centerPointLineX, centerPointLineY), endPoint));

}
return arrowList;
}

• 本文已收录于以下专栏：

## Android ImageCropper 矩形 圆形 裁剪框

• JianTao_Yang
• 2015年02月08日 15:30
• 27161

## android绘图canvas的sava、restore、rotate以及若干问题，canvas绘图的理解

• dinko321
• 2012年06月20日 12:27
• 30076

## 边双连通分量

• kksleric
• 2012年08月12日 09:12
• 813

## Android绘制一条边为弧形的矩形

• GISuuser
• 2018年01月11日 10:55
• 169

## JZOJ8.16(C组)最短路

• qq_34510600
• 2016年08月16日 21:14
• 342

## 蓝桥杯 算法训练 关联矩阵（Java解题）

• mcp3128
• 2017年11月25日 17:24
• 122

## JZOJsenior3470.【NOIP2013模拟联考8】最短路(path)

problemDescription给定一个n个点m条边的有向图，有k个标记点，要求从规定的起点按任意顺序经过所有标记点到达规定的终点，问最短的距离是多少。Input第一行5个整数n、m、k、s、t，...
• enjoy_pascal
• 2017年11月25日 15:41
• 90

## 用VISO 分割线条或图形

• rc_ll
• 2014年03月20日 19:15
• 1701

## 【 CodeForces 209C】 【欧拉回路推结论+并查集计算联通分量】 【给定n点m边无向图，可能有自环和重边。 问最少添加多少条边后，使得图存在从点1出发发又回到点1的欧拉回路】

• guhaiteng
• 2016年10月05日 20:59
• 966

## Android画带圆边的矩形

• onceing
• 2015年04月15日 17:39
• 1259

举报原因： 您举报文章：Android 任意多边形以任意条边画平分线切割图形算法 色情 政治 抄袭 广告 招聘 骂人 其他 (最多只允许输入30个字)