/** 计算两点间距离,结果取数的级别 */ private static float calculateDistance(PointBean start, PointBean end) { float result = 1; float x = Math.abs(start.getX() - end.getX()); float y = Math.abs(start.getY() - end.getY()); String dis = (int) Math.sqrt(x * x + y * y) + ""; int level = dis.trim().length(); for (int i = 1; i < level; ++i) { result *= 10; } return result; }
/** 用两个点算他们的中点,完成一次贝塞尔曲线计算 */ private static void addMidPoint() { PointBean one = mScreenPoints.get(0); PointBean three = mScreenPoints.get(1); PointBean mid = new PointBean(((one.getX() + three.getX()) / 2), (one.getY() + three.getY()) / 2); if (mBezierPoints.size() == 2) { // 前面已经完成一次中点计算了 mBezierPoints.add(mid); calculateBezier(); mBezierPoints.clear(); // 计算完之后,要将这一次的中点和屏幕点记下来,给下一个中点完成贝塞尔曲线 mBezierPoints.add(mid); mBezierPoints.add(three); } else { // 第一次完成中点计算 mBezierPoints.add(one); // 第一个点,以线性的贝塞尔曲线连接 mBezierPoints.add(mid); mBezierPoints.add(three); calculateBezier(); releasePoints(); // 添加点,等下一次用 mBezierPoints.add(mid); mBezierPoints.add(three); } }
/** 计算贝塞尔曲线点 */ private static void calculateBezier() { PointBean mControlPoint; // 贝塞尔控制点 PointBean mBezierPoint; // 贝塞尔曲线上的点 PointBean mStartPoint; // 贝塞尔曲线起点 PointBean mEndPoint; // 贝塞尔曲线终点 float t = 0.01f; // 默认t取0.01 float BezierX; float BezierY; mControlPoint = mBezierPoints.get(1); mStartPoint = mBezierPoints.get(0); mEndPoint = mBezierPoints.get(2); mBezierResult.add(mStartPoint); // 先计算两点之间距离,根据距离选择t float distance; // 起点和终点两点间距离 distance = calculateDistance(mStartPoint, mEndPoint); t = 1 / distance; // 再根据距离选取t的取值 100->0.01, 10->0.1, 1->1 float step = t / 2; // 除以2再取多一点的点 if (t > 0 && t < 1) { // t取值范围 // 公式 (1-t)^2 * x1 + 2 * t * (1-t) * x0 + t^2 * x2 = x for (; t <= 1.0f; t += step) { BezierX = (float) Math.pow(1 - t, 2) * mBezierPoints.get(0).getX() + 2 * t * (1 - t) * mControlPoint.getX() + (float) Math.pow(t, 2) * mBezierPoints.get(2).getX(); BezierY = (float) Math.pow(1 - t, 2) * mBezierPoints.get(0).getY() + 2 * t * (1 - t) * mControlPoint.getY() + (float) Math.pow(t, 2) * mBezierPoints.get(2).getY(); mBezierPoint = new PointBean(BezierX, BezierY); mBezierResult.add(mBezierPoint); } } mBezierResult.add(mEndPoint); switch (Constant.CURRENT_USE_TYPE) { case Constant.PAINT: ObjectUtil.createBezierLine(mBezierResult); break; case Constant.FIREWORKS: // 需要每个点位置刚好接上,不能重叠 mDeleteLeftPoints = splicePoints(mBezierResult); ObjectUtil.createBezierLine(mDeleteLeftPoints); break; case Constant.WALLPAPER: // 需要先除去一些点 mDeleteLeftPoints = deletePoints(mBezierResult); ObjectUtil.createBezierLine(mDeleteLeftPoints); break; case Constant.MOSAIC: ObjectUtil.createBezierLine(mBezierResult); break; case Constant.ERASER: ObjectUtil.createBezierLine(mBezierResult); break; default: break; } }
/** * 也是计算两点间距离,但是这个是结果准确的 * * @param start * @param end * @return */ private static float calculateExactDistance(PointBean start, PointBean end) { float x = Math.abs(start.getX() - end.getX()); float y = Math.abs(start.getY() - end.getY()); return (float) Math.sqrt((x * x + y * y)); }