pda/zhuike/.svn/pristine/e4/e4538f008f52998f2887c300a38...

658 lines
24 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.novelbook.android.view.animation;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PointF;
import android.graphics.Region;
import android.graphics.drawable.GradientDrawable;
import android.os.Build;
import android.util.Log;
import android.widget.Scroller;
public class SimulationAnimation extends AnimationProvider {
private static final String TAG=SimulationAnimation.class.getSimpleName();
private int mCornerX = 1; // 拖拽点对应的页脚
private int mCornerY = 1;
private Path mPath0;
private Path mPath1;
PointF mBezierStart1 = new PointF(); // 贝塞尔曲线起始点
PointF mBezierControl1 = new PointF(); // 贝塞尔曲线控制点
PointF mBeziervertex1 = new PointF(); // 贝塞尔曲线顶点
PointF mBezierEnd1 = new PointF(); // 贝塞尔曲线结束点
PointF mBezierStart2 = new PointF(); // 另一条贝塞尔曲线
PointF mBezierControl2 = new PointF();
PointF mBeziervertex2 = new PointF();
PointF mBezierEnd2 = new PointF();
float mMiddleX;
float mMiddleY;
float mDegrees;
float mTouchToCornerDis;
ColorMatrixColorFilter mColorMatrixFilter;
Matrix mMatrix;
float[] mMatrixArray = { 0, 0, 0, 0, 0, 0, 0, 0, 1.0f };
boolean mIsRTandLB; // 是否属于右上左下
private float mMaxLength ;
int[] mBackShadowColors;// 背面颜色组
int[] mFrontShadowColors;// 前面颜色组
GradientDrawable mBackShadowDrawableLR; // 有阴影的GradientDrawable
GradientDrawable mBackShadowDrawableRL;
GradientDrawable mFolderShadowDrawableLR;
GradientDrawable mFolderShadowDrawableRL;
GradientDrawable mFrontShadowDrawableHBT;
GradientDrawable mFrontShadowDrawableHTB;
GradientDrawable mFrontShadowDrawableVLR;
GradientDrawable mFrontShadowDrawableVRL;
Paint mPaint;
public SimulationAnimation(Bitmap mCurrentBitmap, Bitmap mNextBitmap, int width, int height) {
super(mCurrentBitmap, mNextBitmap, width, height);
mPath0 = new Path();
mPath1 = new Path();
mMaxLength = (float) Math.hypot(mScreenWidth, mScreenHeight);
mPaint = new Paint();
mPaint.setStyle(Paint.Style.FILL);
createDrawable();
ColorMatrix cm = new ColorMatrix();//设置颜色数组
// float array[] = { 0.55f, 0, 0, 0, 80.0f,
// 0, 0.55f, 0, 0, 80.0f,
// 0, 0,0.55f, 0, 80.0f,
// 0, 0, 0, 0.2f, 0 };
float array[] = { 1, 0, 0, 0, 0,
0, 1, 0, 0, 0,
0, 0,1, 0, 0,
0, 0, 0, 1, 0 };
cm.set(array);
mColorMatrixFilter = new ColorMatrixColorFilter(cm);
mMatrix = new Matrix();
mTouch.x = 0.01f; // 不让x,y为0,否则在点计算时会有问题
mTouch.y = 0.01f;
}
@Override
public void drawMove(Canvas canvas) {
Log.d(TAG, "isMoveing drawMove: ");
if (getDirection().equals(Direction.next)) {
calcPoints();
drawCurrentPageArea(canvas, mCurPageBitmap, mPath0);
drawNextPageAreaAndShadow(canvas, mNextPageBitmap);
// drawCurrentPageShadow(canvas); //去除阴影
drawCurrentBackArea(canvas, mCurPageBitmap);
}else{
calcPoints();
drawCurrentPageArea(canvas, mNextPageBitmap, mPath0);
drawNextPageAreaAndShadow(canvas, mCurPageBitmap);
drawCurrentPageShadow(canvas);
drawCurrentBackArea(canvas, mNextPageBitmap);
}
}
@Override
public void drawStatic(Canvas canvas) {
if (getCancel()){
canvas.drawBitmap(mCurPageBitmap, 0, 0, null);
}else {
canvas.drawBitmap(mNextPageBitmap, 0, 0, null);
}
}
@Override
public void setCancel(boolean isCancel) {
super.setCancel(isCancel);
}
@Override
public void startAnimation(Scroller scroller) {
int dx, dy;
// dx 水平方向滑动的距离,负值会使滚动向左滚动
// dy 垂直方向滑动的距离,负值会使滚动向上滚动
if (getCancel()){
if (mCornerX > 0 && getDirection().equals(Direction.next)) {
dx = (int) (mScreenWidth - mTouch.x);
} else {
dx = -(int) mTouch.x;
}
if (!getDirection().equals(Direction.next)){
dx = (int) - (mScreenWidth + mTouch.x);
}
if (mCornerY > 0) {
dy = (int) (mScreenHeight - mTouch.y);
} else {
dy = - (int) mTouch.y; // 防止mTouch.y最终变为0
}
}else {
if (mCornerX > 0 && getDirection().equals(Direction.next)) {
dx = -(int) (mScreenWidth + mTouch.x);
} else {
dx = (int) (mScreenWidth - mTouch.x + mScreenWidth);
}
if (mCornerY > 0) {
dy = (int) (mScreenHeight - mTouch.y);
} else {
dy = (int) (1 - mTouch.y); // 防止mTouch.y最终变为0
}
}
scroller.startScroll((int) mTouch.x, (int) mTouch.y, dx, dy, duation);
}
@Override
public void setDirection(Direction direction) {
super.setDirection(direction);
switch (direction){
case pre:
//上一页滑动不出现对角
if (myStartX > mScreenWidth / 2){
calcCornerXY(myStartX,mScreenHeight);
}else{
calcCornerXY(mScreenWidth - myStartX,mScreenHeight);
}
break;
case next:
if (mScreenWidth / 2 > myStartX){
calcCornerXY(mScreenWidth - myStartX,myStartY);
}
break;
}
}
@Override
public void setStartPoint(float x, float y) {
super.setStartPoint(x, y);
calcCornerXY(x,y);
}
@Override
public void setTouchPoint(float x, float y) {
super.setTouchPoint(x, y);
//触摸y中间位置吧y变成屏幕高度
if ((myStartY > mScreenHeight / 3 && myStartY < mScreenHeight * 2 / 3) || getDirection().equals(Direction.pre)){
mTouch.y = mScreenHeight;
}
if (myStartY > mScreenHeight / 3 && myStartY < mScreenHeight / 2 && getDirection().equals(Direction.next)){
mTouch.y = 1;
}
}
/**
* 创建阴影的GradientDrawable
*/
private void createDrawable() {
int[] color = { 0x333333, 0xb0333333 };
mFolderShadowDrawableRL = new GradientDrawable(
GradientDrawable.Orientation.RIGHT_LEFT, color);
mFolderShadowDrawableRL
.setGradientType(GradientDrawable.LINEAR_GRADIENT);
mFolderShadowDrawableLR = new GradientDrawable(
GradientDrawable.Orientation.LEFT_RIGHT, color);
mFolderShadowDrawableLR
.setGradientType(GradientDrawable.LINEAR_GRADIENT);
mBackShadowColors = new int[] { 0xff111111, 0x111111 };
mBackShadowDrawableRL = new GradientDrawable(
GradientDrawable.Orientation.RIGHT_LEFT, mBackShadowColors);
mBackShadowDrawableRL.setGradientType(GradientDrawable.LINEAR_GRADIENT);
mBackShadowDrawableLR = new GradientDrawable(
GradientDrawable.Orientation.LEFT_RIGHT, mBackShadowColors);
mBackShadowDrawableLR.setGradientType(GradientDrawable.LINEAR_GRADIENT);
mFrontShadowColors = new int[] { 0x80111111, 0x111111 };
mFrontShadowDrawableVLR = new GradientDrawable(
GradientDrawable.Orientation.LEFT_RIGHT, mFrontShadowColors);
mFrontShadowDrawableVLR
.setGradientType(GradientDrawable.LINEAR_GRADIENT);
mFrontShadowDrawableVRL = new GradientDrawable(
GradientDrawable.Orientation.RIGHT_LEFT, mFrontShadowColors);
mFrontShadowDrawableVRL
.setGradientType(GradientDrawable.LINEAR_GRADIENT);
mFrontShadowDrawableHTB = new GradientDrawable(
GradientDrawable.Orientation.TOP_BOTTOM, mFrontShadowColors);
mFrontShadowDrawableHTB
.setGradientType(GradientDrawable.LINEAR_GRADIENT);
mFrontShadowDrawableHBT = new GradientDrawable(
GradientDrawable.Orientation.BOTTOM_TOP, mFrontShadowColors);
mFrontShadowDrawableHBT
.setGradientType(GradientDrawable.LINEAR_GRADIENT);
}
/**
* 是否能够拖动过去
*
* @return
*/
public boolean canDragOver() {
if (mTouchToCornerDis > mScreenWidth / 10)
return true;
return false;
}
public boolean right() {
if (mCornerX > -4)
return false;
return true;
}
/**
* 绘制翻起页背面
*
* @param canvas
* @param bitmap
*/
private void drawCurrentBackArea(Canvas canvas, Bitmap bitmap) {
int i = (int) (mBezierStart1.x + mBezierControl1.x) / 2;
float f1 = Math.abs(i - mBezierControl1.x);
int i1 = (int) (mBezierStart2.y + mBezierControl2.y) / 2;
float f2 = Math.abs(i1 - mBezierControl2.y);
float f3 = Math.min(f1, f2);
mPath1.reset();
mPath1.moveTo(mBeziervertex2.x, mBeziervertex2.y);
mPath1.lineTo(mBeziervertex1.x, mBeziervertex1.y);
mPath1.lineTo(mBezierEnd1.x, mBezierEnd1.y);
mPath1.lineTo(mTouch.x, mTouch.y);
mPath1.lineTo(mBezierEnd2.x, mBezierEnd2.y);
mPath1.close();
GradientDrawable mFolderShadowDrawable;
int left;
int right;
if (mIsRTandLB) {
left = (int) (mBezierStart1.x - 1);
right = (int) (mBezierStart1.x + f3 + 1);
mFolderShadowDrawable = mFolderShadowDrawableLR;
} else {
left = (int) (mBezierStart1.x - f3 - 1);
right = (int) (mBezierStart1.x + 1);
mFolderShadowDrawable = mFolderShadowDrawableRL;
}
canvas.save();
try {
canvas.clipPath(mPath0);
canvas.clipPath(mPath1, Region.Op.INTERSECT);
} catch (Exception e) {
}
mPaint.setColorFilter(mColorMatrixFilter);
float dis = (float) Math.hypot(mCornerX - mBezierControl1.x,
mBezierControl2.y - mCornerY);
float f8 = (mCornerX - mBezierControl1.x) / dis;
float f9 = (mBezierControl2.y - mCornerY) / dis;
mMatrixArray[0] = 1 - 2 * f9 * f9;
mMatrixArray[1] = 2 * f8 * f9;
mMatrixArray[3] = mMatrixArray[1];
mMatrixArray[4] = 1 - 2 * f8 * f8;
mMatrix.reset();
mMatrix.setValues(mMatrixArray);
mMatrix.preTranslate(-mBezierControl1.x, -mBezierControl1.y);
mMatrix.postTranslate(mBezierControl1.x, mBezierControl1.y);
// mPaint.setAlpha(0x90);
canvas.drawBitmap(bitmap, mMatrix, mPaint);
// canvas.drawBitmap(bitmap, mMatrix, null);
mPaint.setColorFilter(null);
canvas.rotate(mDegrees, mBezierStart1.x, mBezierStart1.y);
mFolderShadowDrawable.setBounds(left, (int) mBezierStart1.y, right, (int) (mBezierStart1.y + mMaxLength));
mFolderShadowDrawable.draw(canvas);
canvas.restore();
}
/**
* 绘制翻起页的阴影
*
* @param canvas
*/
public void drawCurrentPageShadow(Canvas canvas) {
double degree;
if (mIsRTandLB) {
degree = Math.PI
/ 4
- Math.atan2(mBezierControl1.y - mTouch.y, mTouch.x
- mBezierControl1.x);
} else {
degree = Math.PI
/ 4
- Math.atan2(mTouch.y - mBezierControl1.y, mTouch.x
- mBezierControl1.x);
}
// 翻起页阴影顶点与touch点的距离
double d1 = (float) 25 * 1.414 * Math.cos(degree);
double d2 = (float) 25 * 1.414 * Math.sin(degree);
float x = (float) (mTouch.x + d1);
float y;
if (mIsRTandLB) {
y = (float) (mTouch.y + d2);
} else {
y = (float) (mTouch.y - d2);
}
mPath1.reset();
mPath1.moveTo(x, y);
mPath1.lineTo(mTouch.x, mTouch.y);
mPath1.lineTo(mBezierControl1.x, mBezierControl1.y);
mPath1.lineTo(mBezierStart1.x, mBezierStart1.y);
mPath1.close();
float rotateDegrees;
canvas.save();
try {
canvas.clipPath(mPath0, Region.Op.XOR);
canvas.clipPath(mPath1, Region.Op.INTERSECT);
} catch (Exception e) {
// TODO: handle exception
}
int leftx;
int rightx;
GradientDrawable mCurrentPageShadow;
if (mIsRTandLB) {
leftx = (int) (mBezierControl1.x);
rightx = (int) mBezierControl1.x + 25;
mCurrentPageShadow = mFrontShadowDrawableVLR;
} else {
leftx = (int) (mBezierControl1.x - 25);
rightx = (int) mBezierControl1.x + 1;
mCurrentPageShadow = mFrontShadowDrawableVRL;
}
rotateDegrees = (float) Math.toDegrees(Math.atan2(mTouch.x
- mBezierControl1.x, mBezierControl1.y - mTouch.y));
canvas.rotate(rotateDegrees, mBezierControl1.x, mBezierControl1.y);
mCurrentPageShadow.setBounds(leftx,
(int) (mBezierControl1.y - mMaxLength), rightx,
(int) (mBezierControl1.y));
mCurrentPageShadow.draw(canvas);
canvas.restore();
mPath1.reset();
mPath1.moveTo(x, y);
mPath1.lineTo(mTouch.x, mTouch.y);
mPath1.lineTo(mBezierControl2.x, mBezierControl2.y);
mPath1.lineTo(mBezierStart2.x, mBezierStart2.y);
mPath1.close();
canvas.save();
try {
canvas.clipPath(mPath0, Region.Op.XOR);
canvas.clipPath(mPath1, Region.Op.INTERSECT);
} catch (Exception e) {
}
if (mIsRTandLB) {
leftx = (int) (mBezierControl2.y);
rightx = (int) (mBezierControl2.y + 25);
mCurrentPageShadow = mFrontShadowDrawableHTB;
} else {
leftx = (int) (mBezierControl2.y - 25);
rightx = (int) (mBezierControl2.y + 1);
mCurrentPageShadow = mFrontShadowDrawableHBT;
}
rotateDegrees = (float) Math.toDegrees(Math.atan2(mBezierControl2.y
- mTouch.y, mBezierControl2.x - mTouch.x));
canvas.rotate(rotateDegrees, mBezierControl2.x, mBezierControl2.y);
float temp;
if (mBezierControl2.y < 0)
temp = mBezierControl2.y - mScreenHeight;
else
temp = mBezierControl2.y;
int hmg = (int) Math.hypot(mBezierControl2.x, temp);
if (hmg > mMaxLength)
mCurrentPageShadow
.setBounds((int) (mBezierControl2.x - 25) - hmg, leftx,
(int) (mBezierControl2.x + mMaxLength) - hmg,
rightx);
else
mCurrentPageShadow.setBounds(
(int) (mBezierControl2.x - mMaxLength), leftx,
(int) (mBezierControl2.x), rightx);
// Log.i("hmg", "mBezierControl2.x " + mBezierControl2.x
// + " mBezierControl2.y " + mBezierControl2.y);
mCurrentPageShadow.draw(canvas);
canvas.restore();
}
private void drawNextPageAreaAndShadow(Canvas canvas, Bitmap bitmap) {
mPath1.reset();
mPath1.moveTo(mBezierStart1.x, mBezierStart1.y);
mPath1.lineTo(mBeziervertex1.x, mBeziervertex1.y);
mPath1.lineTo(mBeziervertex2.x, mBeziervertex2.y);
mPath1.lineTo(mBezierStart2.x, mBezierStart2.y);
mPath1.lineTo(mCornerX, mCornerY);
mPath1.close();
mDegrees = (float) Math.toDegrees(Math.atan2(mBezierControl1.x
- mCornerX, mBezierControl2.y - mCornerY));
int leftx;
int rightx;
GradientDrawable mBackShadowDrawable;
if (mIsRTandLB) { //左下及右上
leftx = (int) (mBezierStart1.x);
rightx = (int) (mBezierStart1.x + mTouchToCornerDis / 4);
mBackShadowDrawable = mBackShadowDrawableLR;
} else {
leftx = (int) (mBezierStart1.x - mTouchToCornerDis / 4);
rightx = (int) mBezierStart1.x;
mBackShadowDrawable = mBackShadowDrawableRL;
}
canvas.save();
try {
canvas.clipPath(mPath0);
canvas.clipPath(mPath1, Region.Op.INTERSECT);
} catch (Exception e) {
}
canvas.drawBitmap(bitmap, 0, 0, null);
canvas.rotate(mDegrees, mBezierStart1.x, mBezierStart1.y);
mBackShadowDrawable.setBounds(leftx, (int) mBezierStart1.y, rightx,
(int) (mMaxLength + mBezierStart1.y));//左上及右下角的xy坐标值,构成一个矩形
mBackShadowDrawable.draw(canvas);
canvas.restore();
}
private void drawCurrentPageArea(Canvas canvas, Bitmap bitmap, Path path) {
mPath0.reset();
mPath0.moveTo(mBezierStart1.x, mBezierStart1.y);
mPath0.quadTo(mBezierControl1.x, mBezierControl1.y, mBezierEnd1.x,
mBezierEnd1.y);
mPath0.lineTo(mTouch.x, mTouch.y);
mPath0.lineTo(mBezierEnd2.x, mBezierEnd2.y);
mPath0.quadTo(mBezierControl2.x, mBezierControl2.y, mBezierStart2.x,
mBezierStart2.y);
mPath0.lineTo(mCornerX, mCornerY);
mPath0.close();
canvas.save();
if(Build.VERSION.SDK_INT >= 26){
// canvas.clipPath(path); //将正面变空白了
}else {
// canvas.clipPath(path, Region.Op.XOR); //未试过,低版本手机上效果如何?
}
canvas.drawBitmap(bitmap, 0, 0, null);
try {
canvas.restore();
} catch (Exception e) {
}
}
/**
* 计算拖拽点对应的拖拽脚
*
* @param x
* @param y
*/
public void calcCornerXY(float x, float y) {
// Log.i("hck", "PageWidget x:" + x + " y" + y);
if (x <= mScreenWidth / 2) {
mCornerX = 0;
}else {
mCornerX = mScreenWidth;
}
if (y <= mScreenHeight / 2) {
mCornerY = 0;
} else {
mCornerY = mScreenHeight;
}
if ((mCornerX == 0 && mCornerY == mScreenHeight)
|| (mCornerX == mScreenWidth && mCornerY == 0)) {
mIsRTandLB = true;
}else {
mIsRTandLB = false;
}
}
private void calcPoints() {
mMiddleX = (mTouch.x + mCornerX) / 2;
mMiddleY = (mTouch.y + mCornerY) / 2;
mBezierControl1.x = mMiddleX - (mCornerY - mMiddleY)
* (mCornerY - mMiddleY) / (mCornerX - mMiddleX);
mBezierControl1.y = mCornerY;
mBezierControl2.x = mCornerX;
// mBezierControl2.y = mMiddleY - (mCornerX - mMiddleX)
// * (mCornerX - mMiddleX) / (mCornerY - mMiddleY);
float f4 = mCornerY-mMiddleY;
if (f4 == 0) {
mBezierControl2.y = mMiddleY - (mCornerX - mMiddleX)
* (mCornerX - mMiddleX) / 0.1f;
// Log.d("PageWidget",""+f4);
}else {
mBezierControl2.y = mMiddleY - (mCornerX - mMiddleX)
* (mCornerX - mMiddleX) / (mCornerY - mMiddleY);
// Log.d("PageWidget","没有进入if判断"+ mBezierControl2.y + "");
}
// Log.i("hmg", "mTouchX " + mTouch.x + " mTouchY " + mTouch.y);
// Log.i("hmg", "mBezierControl1.x " + mBezierControl1.x
// + " mBezierControl1.y " + mBezierControl1.y);
// Log.i("hmg", "mBezierControl2.x " + mBezierControl2.x
// + " mBezierControl2.y " + mBezierControl2.y);
mBezierStart1.x = mBezierControl1.x - (mCornerX - mBezierControl1.x)
/ 2;
mBezierStart1.y = mCornerY;
// 当mBezierStart1.x < 0或者mBezierStart1.x > 480时
// 如果继续翻页会出现BUG故在此限制
if (mTouch.x > 0 && mTouch.x < mScreenWidth) {
if (mBezierStart1.x < 0 || mBezierStart1.x > mScreenWidth) {
if (mBezierStart1.x < 0)
mBezierStart1.x = mScreenWidth - mBezierStart1.x;
float f1 = Math.abs(mCornerX - mTouch.x);
float f2 = mScreenWidth * f1 / mBezierStart1.x;
mTouch.x = Math.abs(mCornerX - f2);
float f3 = Math.abs(mCornerX - mTouch.x)
* Math.abs(mCornerY - mTouch.y) / f1;
mTouch.y = Math.abs(mCornerY - f3);
mMiddleX = (mTouch.x + mCornerX) / 2;
mMiddleY = (mTouch.y + mCornerY) / 2;
mBezierControl1.x = mMiddleX - (mCornerY - mMiddleY)
* (mCornerY - mMiddleY) / (mCornerX - mMiddleX);
mBezierControl1.y = mCornerY;
mBezierControl2.x = mCornerX;
// mBezierControl2.y = mMiddleY - (mCornerX - mMiddleX)
// * (mCornerX - mMiddleX) / (mCornerY - mMiddleY);
float f5 = mCornerY-mMiddleY;
if (f5 == 0) {
mBezierControl2.y = mMiddleY - (mCornerX - mMiddleX)
* (mCornerX - mMiddleX) / 0.1f;
}else {
mBezierControl2.y = mMiddleY - (mCornerX - mMiddleX)
* (mCornerX - mMiddleX) / (mCornerY - mMiddleY);
// Log.d("PageWidget", mBezierControl2.y + "");
}
// Log.i("hmg", "mTouchX --> " + mTouch.x + " mTouchY--> "
// + mTouch.y);
// Log.i("hmg", "mBezierControl1.x-- " + mBezierControl1.x
// + " mBezierControl1.y -- " + mBezierControl1.y);
// Log.i("hmg", "mBezierControl2.x -- " + mBezierControl2.x
// + " mBezierControl2.y -- " + mBezierControl2.y);
mBezierStart1.x = mBezierControl1.x
- (mCornerX - mBezierControl1.x) / 2;
}
}
mBezierStart2.x = mCornerX;
mBezierStart2.y = mBezierControl2.y - (mCornerY - mBezierControl2.y)
/ 2;
mTouchToCornerDis = (float) Math.hypot((mTouch.x - mCornerX),
(mTouch.y - mCornerY));
mBezierEnd1 = getCross(mTouch, mBezierControl1, mBezierStart1,
mBezierStart2);
mBezierEnd2 = getCross(mTouch, mBezierControl2, mBezierStart1,
mBezierStart2);
// Log.i("hmg", "mBezierEnd1.x " + mBezierEnd1.x + " mBezierEnd1.y "
// + mBezierEnd1.y);
// Log.i("hmg", "mBezierEnd2.x " + mBezierEnd2.x + " mBezierEnd2.y "
// + mBezierEnd2.y);
/*
* mBeziervertex1.x 推导
* ((mBezierStart1.x+mBezierEnd1.x)/2+mBezierControl1.x)/2 化简等价于
* (mBezierStart1.x+ 2*mBezierControl1.x+mBezierEnd1.x) / 4
*/
mBeziervertex1.x = (mBezierStart1.x + 2 * mBezierControl1.x + mBezierEnd1.x) / 4;
mBeziervertex1.y = (2 * mBezierControl1.y + mBezierStart1.y + mBezierEnd1.y) / 4;
mBeziervertex2.x = (mBezierStart2.x + 2 * mBezierControl2.x + mBezierEnd2.x) / 4;
mBeziervertex2.y = (2 * mBezierControl2.y + mBezierStart2.y + mBezierEnd2.y) / 4;
}
/**
* 求解直线P1P2和直线P3P4的交点坐标
*
* @param P1
* @param P2
* @param P3
* @param P4
* @return
*/
public PointF getCross(PointF P1, PointF P2, PointF P3, PointF P4) {
PointF CrossP = new PointF();
// 二元函数通式: y=ax+b
float a1 = (P2.y - P1.y) / (P2.x - P1.x);
float b1 = ((P1.x * P2.y) - (P2.x * P1.y)) / (P1.x - P2.x);
float a2 = (P4.y - P3.y) / (P4.x - P3.x);
float b2 = ((P3.x * P4.y) - (P4.x * P3.y)) / (P3.x - P4.x);
CrossP.x = (b2 - b1) / (a1 - a2);
CrossP.y = a1 * CrossP.x + b1;
return CrossP;
}
}