下面列出了android.graphics.Path#rLineTo ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private Path createRoundedRectPathApi21(Path path, float left, float top, float right, float bottom, float rx, float ry) {
if (rx < 0) rx = 0;
if (ry < 0) ry = 0;
float width = right - left;
float height = bottom - top;
if (rx > width / 2) rx = width / 2;
if (ry > height / 2) ry = height / 2;
float widthMinusCorners = (width - (2 * rx));
float heightMinusCorners = (height - (2 * ry));
path.moveTo(right, top + ry);
path.arcTo(right - 2 * rx, top, right, top + 2 * ry, 0, -90, false);
path.rLineTo(-widthMinusCorners, 0);
path.arcTo(left, top, left + 2 * rx, top + 2 * ry, 270, -90, false);
path.rLineTo(0, heightMinusCorners);
path.arcTo(left, bottom - 2 * ry, left + 2 * rx, bottom, 180, -90, false);
path.rLineTo(widthMinusCorners, 0);
path.arcTo(right - 2 * rx, bottom - 2 * ry, right, bottom, 90, -90, false);
path.rLineTo(0, -heightMinusCorners);
path.close();
return path;
}
@Override
public Path getBlockShape(int blockSize) {
int gap = (int) (blockSize/5f);
Path path = new Path();
path.moveTo(0, gap);
path.rLineTo(blockSize/2.5f, 0);
path.rLineTo(0, -gap);
path.rLineTo(gap, 0);
path.rLineTo(0, gap);
path.rLineTo(2 * gap, 0);
path.rLineTo(0, 4 * gap);
path.rLineTo(-5 * gap, 0);
path.rLineTo(0, -1.5f * gap);
path.rLineTo(gap, 0);
path.rLineTo(0, -gap);
path.rLineTo(-gap, 0);
path.close();
return path;
}
private void init(float left, float top, float right, float bottom, float rx, float ry,
boolean applyRoundToTopLeft, boolean applyRoundToTopRight,
boolean applyRoundToBottomRight, boolean applyRoundToBottomLeft) {
float width = right - left;
float height = bottom - top;
rx = normalizeValue(rx, 0, width / 2);
ry = normalizeValue(ry, 0, height / 2);
float widthMinusCorners = (width - (2 * rx));
float heightMinusCorners = (height - (2 * ry));
path = new Path();
path.moveTo(right, top + ry);
drawTopRightCorner(rx, ry, applyRoundToTopRight);
path.rLineTo(-widthMinusCorners, 0);
drawTopLeftCorner(rx, ry, applyRoundToTopLeft);
path.rLineTo(0, heightMinusCorners);
drawBottomLeftCorner(rx, ry, applyRoundToBottomLeft);
path.rLineTo(widthMinusCorners, 0);
drawBottomRightCorner(rx, ry, applyRoundToBottomRight);
path.rLineTo(0, -heightMinusCorners);
path.close();
}
@Override
public void setBounds(int left, int top, int right, int bottom) {
Rect bounds = getBounds();
if (bounds.left != left || bounds.top != top || bounds.right != right || bounds.bottom != bottom) {
Path path = this.path;
path.rewind();
float radius = this.radius;
float shift = ((float) Math.sqrt(2) - 1f) * radius * 4f / 3f;
path.moveTo(left, top);
path.rLineTo(radius, 0);
path.rCubicTo(-shift, 0, -radius, radius - shift, -radius, radius);
path.close();
path.moveTo(right, top);
path.rLineTo(-radius, 0);
path.rCubicTo(shift, 0, radius, radius - shift, radius, radius);
path.close();
path.moveTo(left, bottom);
path.rLineTo(radius, 0);
path.rCubicTo(-shift, 0, -radius, shift - radius, -radius, -radius);
path.close();
path.moveTo(right, bottom);
path.rLineTo(-radius, 0);
path.rCubicTo(shift, 0, radius, shift - radius, radius, -radius);
path.close();
}
super.setBounds(left, top, right, bottom);
}
/**
* Draws the label for a satellite range.
*
* @param canvas The {@code Canvas} on which the SNR view will appear.
* @param label The text to be displayed (the description of the satellite range, such as "GPS", "GLONASS" or "Beidou")
* @param startBar The NMEA ID of the first satellite in the range
* @param rangeBars The number of NMEA IDs in the range (ranges must be contiguous)
* @param numBars Total number of SNR bars being displayed, as returned by getNumBars()
*/
private void drawLabel(Canvas canvas, String label, int startBar, int rangeBars, int numBars) {
int offsetBars = getGridPos(startBar) - 1;
int w = getWidth();
int h = getHeight();
Path labelPath = new Path();
labelPath.reset();
labelPath.moveTo(gridStrokeWidth + offsetBars * (w - gridStrokeWidth) / numBars, h);
labelPath.rLineTo(rangeBars * (w - gridStrokeWidth) / numBars - gridStrokeWidth, 0);
canvas.drawTextOnPath(label, labelPath, 0, -labelPaint.descent(), labelPaint);
}
private void roundedRect(Path path, float left, float top, float right, float bottom, float rx, float ry,
boolean tl, boolean tr) {
path.reset();
if (rx < 0) rx = 0;
if (ry < 0) ry = 0;
float width = right - left;
float height = bottom - top;
if (rx > width / 2) rx = width / 2;
if (ry > height / 2) ry = height / 2;
float widthMinusCorners = (width - (2 * rx));
float heightMinusCorners = (height - (2 * ry));
path.moveTo(right, top + ry);
if (tr)
path.rQuadTo(0, -ry, -rx, -ry);
else {
path.rLineTo(0, -ry);
path.rLineTo(-rx, 0);
}
path.rLineTo(-widthMinusCorners, 0);
if (tl)
path.rQuadTo(-rx, 0, -rx, ry);
else {
path.rLineTo(-rx, 0);
path.rLineTo(0, ry);
}
path.rLineTo(0, heightMinusCorners);
path.rLineTo(0, ry);
path.rLineTo(rx, 0);
path.rLineTo(widthMinusCorners, 0);
path.rLineTo(rx, 0);
path.rLineTo(0, -ry);
path.rLineTo(0, -heightMinusCorners);
path.close();
}
@Override
public FloatingPath getFloatingPath() {
Path path = new Path();
path.moveTo(0, 0);
// path.cubicTo(-300,-200,-300,-900,0,-1800);
path.quadTo(300, -300, 0, -600);
path.quadTo(0, -600,-300,-900);
path.quadTo(-300, -900,0,-1200);
path.rLineTo(0, -1920 -300);
return FloatingPath.create(path, false);
}
static public Path RoundedRect(float left, float top, float right, float bottom, float rx, float ry, boolean conformToOriginalPost) {
Path path = new Path();
if (rx < 0) rx = 0;
if (ry < 0) ry = 0;
float width = right - left;
float height = bottom - top;
if (rx > width/2) rx = width/2;
if (ry > height/2) ry = height/2;
float widthMinusCorners = (width - (2 * rx)); // do dai phan "thang" cua chieu rong
float heightMinusCorners = (height - (2 * ry)); // do dai phan "thang" cua chieu dai
path.moveTo(right, top + ry); // bat dau tu day
path.rQuadTo(0, -ry, -rx, -ry);//y-right corner
path.rLineTo(-widthMinusCorners, 0);
path.rQuadTo(-rx, 0, -rx, ry); //y-x corner
path.rLineTo(0, heightMinusCorners);
if (conformToOriginalPost) {
path.rLineTo(0, ry);
path.rLineTo(width, 0);
path.rLineTo(0, -ry);
}
else {
path.rQuadTo(0, ry, rx, ry);//bottom-x corner
path.rLineTo(widthMinusCorners, 0);
path.rQuadTo(rx, 0, rx, -ry); //bottom-right corner
}
path.rLineTo(0, -heightMinusCorners);
path.close();//Given close, last lineto can be removed.
return path;
}
@Override
public FloatingPath getFloatingPath() {
Path path = new Path();
path.moveTo(0, 0);
path.quadTo(100, -300, 0, -600);
path.rLineTo(0, -mScreenHeight - 300);
return FloatingPath.create(path, false);
}
@Override
public FloatingPath getFloatingPath() {
Path path = new Path();
path.rLineTo(-100,0);
path.quadTo(0,-200,100,0);
path.quadTo(0,200,-100,0);
return FloatingPath.create(path, false);
}
private Bitmap getWave() {
int count = (int) Math.ceil(width / mLength);
canvas.drawColor(Color.YELLOW, PorterDuff.Mode.CLEAR);
Path path = new Path();
path.moveTo(0, 0);
for (int i = 0; i < count * 2; i++) {
path.quadTo(mLength / 4 + i * mLength, mAmplitude * 2, mLength / 2 + i * mLength, 0);
path.quadTo(mLength * 3 / 4 + i * mLength, -mAmplitude * 2, mLength + i * mLength, 0);
}
//rectf.height()+mAmplitude 是因为进度为100的时候 下面不会出现暴露的假象
path.rLineTo(0, height + mAmplitude);
path.rLineTo(-count * 2 * mLength, 0);
path.close();
//弄到进度为0的位置
path.offset(0, height + mAmplitude);
//通过进度计算应该往上偏移多少
float progressOffset = (height + mAmplitude * 2) * mLevelProgress;
path.offset(0, -progressOffset);
//计算水平速度
path.offset(-speedOffsetX - offsetXRadioOfLength * mLength, 0);
canvas.drawPath(path, mPaint);
return waveBitmap;
}
private Path getLinePath(Canvas canvas, float side, float width) {
Rect bound = getBounds();
Path result = new Path();
result.moveTo(bound.right - side, bound.bottom);
result.rLineTo(-width, 0f);
result.lineTo(bound.right, bound.bottom - side - width);
result.rLineTo(0f, width);
result.close();
return result;
}
public static Path RoundedRect(
Path path,
float left, float top, float right, float bottom, float rx, float ry,
boolean tl, boolean tr, boolean br, boolean bl
) {
path.reset();
if (rx < 0) rx = 0;
if (ry < 0) ry = 0;
float width = right - left;
float height = bottom - top;
if (rx > width / 2) rx = width / 2;
if (ry > height / 2) ry = height / 2;
float widthMinusCorners = (width - (2 * rx));
float heightMinusCorners = (height - (2 * ry));
path.moveTo(right, top + ry);
if (tr)
path.rQuadTo(0, -ry, -rx, -ry);
else {
path.rLineTo(0, -ry);
path.rLineTo(-rx, 0);
}
path.rLineTo(-widthMinusCorners, 0);
if (tl)
path.rQuadTo(-rx, 0, -rx, ry);
else {
path.rLineTo(-rx, 0);
path.rLineTo(0, ry);
}
path.rLineTo(0, heightMinusCorners);
if (bl)
path.rQuadTo(0, ry, rx, ry);
else {
path.rLineTo(0, ry);
path.rLineTo(rx, 0);
}
path.rLineTo(widthMinusCorners, 0);
if (br)
path.rQuadTo(rx, 0, rx, -ry);
else {
path.rLineTo(rx, 0);
path.rLineTo(0, -ry);
}
path.rLineTo(0, -heightMinusCorners);
path.close();
return path;
}
/**
* Converts an arc to cubic Bezier segments and records them in p.
*
* @param p The target for the cubic Bezier segments
* @param cx The x coordinate center of the ellipse
* @param cy The y coordinate center of the ellipse
* @param a The radius of the ellipse in the horizontal direction
* @param b The radius of the ellipse in the vertical direction
* @param e1x E(eta1) x coordinate of the starting point of the arc
* @param e1y E(eta2) y coordinate of the starting point of the arc
* @param theta The angle that the ellipse bounding rectangle makes with horizontal plane
* @param start The start angle of the arc on the ellipse
* @param sweep The angle (positive or negative) of the sweep of the arc on the ellipse
*/
private static void arcToBezier(Path p,
double cx,
double cy,
double a,
double b,
double e1x,
double e1y,
double theta,
double start,
double sweep) {
// Taken from equations at: http://spaceroots.org/documents/ellipse/node8.html
// and http://www.spaceroots.org/documents/ellipse/node22.html
// Maximum of 45 degrees per cubic Bezier segment
int numSegments = (int) Math.ceil(Math.abs(sweep * 4 / Math.PI));
double eta1 = start;
double cosTheta = Math.cos(theta);
double sinTheta = Math.sin(theta);
double cosEta1 = Math.cos(eta1);
double sinEta1 = Math.sin(eta1);
double ep1x = (-a * cosTheta * sinEta1) - (b * sinTheta * cosEta1);
double ep1y = (-a * sinTheta * sinEta1) + (b * cosTheta * cosEta1);
double anglePerSegment = sweep / numSegments;
for (int i = 0; i < numSegments; i++) {
double eta2 = eta1 + anglePerSegment;
double sinEta2 = Math.sin(eta2);
double cosEta2 = Math.cos(eta2);
double e2x = cx + (a * cosTheta * cosEta2) - (b * sinTheta * sinEta2);
double e2y = cy + (a * sinTheta * cosEta2) + (b * cosTheta * sinEta2);
double ep2x = -a * cosTheta * sinEta2 - b * sinTheta * cosEta2;
double ep2y = -a * sinTheta * sinEta2 + b * cosTheta * cosEta2;
double tanDiff2 = Math.tan((eta2 - eta1) / 2);
double alpha =
Math.sin(eta2 - eta1) * (Math.sqrt(4 + (3 * tanDiff2 * tanDiff2)) - 1) / 3;
double q1x = e1x + alpha * ep1x;
double q1y = e1y + alpha * ep1y;
double q2x = e2x - alpha * ep2x;
double q2y = e2y - alpha * ep2y;
// Adding this no-op call to workaround a proguard related issue.
p.rLineTo(0, 0);
p.cubicTo((float) q1x,
(float) q1y,
(float) q2x,
(float) q2y,
(float) e2x,
(float) e2y);
eta1 = eta2;
e1x = e2x;
e1y = e2y;
ep1x = ep2x;
ep1y = ep2y;
}
}
/**
* Converts an arc to cubic Bezier segments and records them in p.
*
* @param p The target for the cubic Bezier segments
* @param cx The x coordinate center of the ellipse
* @param cy The y coordinate center of the ellipse
* @param a The radius of the ellipse in the horizontal direction
* @param b The radius of the ellipse in the vertical direction
* @param e1x E(eta1) x coordinate of the starting point of the arc
* @param e1y E(eta2) y coordinate of the starting point of the arc
* @param theta The angle that the ellipse bounding rectangle makes with horizontal plane
* @param start The start angle of the arc on the ellipse
* @param sweep The angle (positive or negative) of the sweep of the arc on the ellipse
*/
private static void arcToBezier(Path p,
double cx,
double cy,
double a,
double b,
double e1x,
double e1y,
double theta,
double start,
double sweep) {
// Taken from equations at: http://spaceroots.org/documents/ellipse/node8.html
// and http://www.spaceroots.org/documents/ellipse/node22.html
// Maximum of 45 degrees per cubic Bezier segment
int numSegments = (int) Math.ceil(Math.abs(sweep * 4 / Math.PI));
double eta1 = start;
double cosTheta = Math.cos(theta);
double sinTheta = Math.sin(theta);
double cosEta1 = Math.cos(eta1);
double sinEta1 = Math.sin(eta1);
double ep1x = (-a * cosTheta * sinEta1) - (b * sinTheta * cosEta1);
double ep1y = (-a * sinTheta * sinEta1) + (b * cosTheta * cosEta1);
double anglePerSegment = sweep / numSegments;
for (int i = 0; i < numSegments; i++) {
double eta2 = eta1 + anglePerSegment;
double sinEta2 = Math.sin(eta2);
double cosEta2 = Math.cos(eta2);
double e2x = cx + (a * cosTheta * cosEta2) - (b * sinTheta * sinEta2);
double e2y = cy + (a * sinTheta * cosEta2) + (b * cosTheta * sinEta2);
double ep2x = -a * cosTheta * sinEta2 - b * sinTheta * cosEta2;
double ep2y = -a * sinTheta * sinEta2 + b * cosTheta * cosEta2;
double tanDiff2 = Math.tan((eta2 - eta1) / 2);
double alpha =
Math.sin(eta2 - eta1) * (Math.sqrt(4 + (3 * tanDiff2 * tanDiff2)) - 1) / 3;
double q1x = e1x + alpha * ep1x;
double q1y = e1y + alpha * ep1y;
double q2x = e2x - alpha * ep2x;
double q2y = e2y - alpha * ep2y;
// Adding this no-op call to workaround a proguard related issue.
p.rLineTo(0, 0);
p.cubicTo((float) q1x,
(float) q1y,
(float) q2x,
(float) q2y,
(float) e2x,
(float) e2y);
eta1 = eta2;
e1x = e2x;
e1y = e2y;
ep1x = ep2x;
ep1y = ep2y;
}
}
protected void drawText(float scaledWidth, Path mainPath, GISDisplay display) {
if (TextUtils.isEmpty(mText) || mainPath == null)
return;
Paint textPaint = new Paint();
textPaint.setColor(mOutColor);
textPaint.setAntiAlias(true);
textPaint.setStyle(Paint.Style.FILL);
textPaint.setStrokeCap(Paint.Cap.ROUND);
textPaint.setStrokeWidth(scaledWidth);
float textSize = 12 * scaledWidth;
textPaint.setTextSize(textSize);
float textWidth = textPaint.measureText(mText);
float vOffset = (float) (textSize / 2.7);
// draw text along the main path
PathMeasure pm = new PathMeasure(mainPath, false);
float length = pm.getLength();
float gap = textPaint.measureText("_");
float period = textWidth + gap;
float startD = gap;
float stopD = startD + period;
Path textPath = new Path();
while (stopD < length) {
textPath.reset();
pm.getSegment(startD, stopD, textPath, true);
textPath.rLineTo(0, 0); // workaround for API <= 19
display.drawTextOnPath(mText, textPath, 0, vOffset, textPaint);
startD += period;
stopD += period;
}
stopD = startD;
float rest = length - stopD;
if (rest > gap * 2) {
stopD = length - gap;
textPath.reset();
pm.getSegment(startD, stopD, textPath, true);
textPath.rLineTo(0, 0); // workaround for API <= 19
display.drawTextOnPath(mText, textPath, 0, vOffset, textPaint);
}
}
static Path roundedRect(float left, float top, float right, float bottom,
float rx, float ry, boolean tl, boolean tr, boolean br, boolean bl) {
Path path = new Path();
if (rx < 0) {
rx = 0f;
}
if (ry < 0) {
ry = 0f;
}
float width = right - left;
float height = bottom - top;
if (rx > width / 2) {
rx = width / 2;
}
if (ry > height / 2) {
ry = height / 2;
}
float widthMinusCorners = width - 2 * rx;
float heightMinusCorners = height - 2 * ry;
path.moveTo(right, top + ry);
if (tr) {
path.rQuadTo(0f, -ry, -rx, -ry);//top-right corner
} else {
path.rLineTo(0f, -ry);
path.rLineTo(-rx, 0f);
}
path.rLineTo(-widthMinusCorners, 0f);
if (tl) {
path.rQuadTo(-rx, 0f, -rx, ry); //top-left corner
} else {
path.rLineTo(-rx, 0f);
path.rLineTo(0f, ry);
}
path.rLineTo(0f, heightMinusCorners);
if (bl) {
path.rQuadTo(0f, ry, rx, ry);//bottom-left corner
} else {
path.rLineTo(0f, ry);
path.rLineTo(rx, 0f);
}
path.rLineTo(widthMinusCorners, 0f);
if (br) {
path.rQuadTo(rx, 0f, rx, -ry); //bottom-right corner
} else {
path.rLineTo(rx, 0f);
path.rLineTo(0f, -ry);
}
path.rLineTo(0f, -heightMinusCorners);
path.close();//Given close, last lineto can be removed.
return path;
}
public static Path RoundedRect(
Path path,
float left, float top, float right, float bottom, float rx, float ry,
boolean tl, boolean tr, boolean br, boolean bl
) {
path.reset();
if (rx < 0) rx = 0;
if (ry < 0) ry = 0;
float width = right - left;
float height = bottom - top;
if (rx > width / 2) rx = width / 2;
if (ry > height / 2) ry = height / 2;
float widthMinusCorners = (width - (2 * rx));
float heightMinusCorners = (height - (2 * ry));
path.moveTo(right, top + ry);
if (tr)
path.rQuadTo(0, -ry, -rx, -ry);
else {
path.rLineTo(0, -ry);
path.rLineTo(-rx, 0);
}
path.rLineTo(-widthMinusCorners, 0);
if (tl)
path.rQuadTo(-rx, 0, -rx, ry);
else {
path.rLineTo(-rx, 0);
path.rLineTo(0, ry);
}
path.rLineTo(0, heightMinusCorners);
if (bl)
path.rQuadTo(0, ry, rx, ry);
else {
path.rLineTo(0, ry);
path.rLineTo(rx, 0);
}
path.rLineTo(widthMinusCorners, 0);
if (br)
path.rQuadTo(rx, 0, rx, -ry);
else {
path.rLineTo(rx, 0);
path.rLineTo(0, -ry);
}
path.rLineTo(0, -heightMinusCorners);
path.close();
return path;
}
public void init() {
float temp = height / 7f;
monthHeight = 0;//(float) ((temp + temp * 0.3f) * 0.6);
//monthChangeWidth = monthHeight * 1.5f;
weekHeight = temp;//(float) ((temp + temp * 0.3f) * 0.7);
cellHeight = temp;//(height - monthHeight - weekHeight) / 6f;
cellWidth = width / 7f;
borderPaint = new Paint();
borderPaint.setColor(borderColor);
borderPaint.setStyle(Paint.Style.STROKE);
borderWidth = (float) (0.5 * density);
// Log.d(TAG, "borderwidth:" + borderWidth);
borderWidth = borderWidth < 1 ? 1 : borderWidth;
borderPaint.setStrokeWidth(borderWidth);
borderPaint.setAlpha(0);
monthPaint = new Paint();
monthPaint.setColor(textColor);
monthPaint.setAntiAlias(true);
float textSize = cellHeight * 0.4f;
monthPaint.setTextSize(textSize);
monthPaint.setTypeface(Typeface.DEFAULT_BOLD);
weekPaint = new Paint();
weekPaint.setColor(textColor);
weekPaint.setAntiAlias(true);
weekPaint.setTextSize(CommUtil.getRawSize(getContext(), TypedValue.COMPLEX_UNIT_SP, weekTextSize));
weekPaint.setTypeface(Typeface.DEFAULT);
datePaint = new Paint();
datePaint.setColor(textColor);
datePaint.setAntiAlias(true);
datePaint.setTextSize(CommUtil.getRawSize(getContext(), TypedValue.COMPLEX_UNIT_SP, cellTextSize));
datePaint.setTypeface(Typeface.DEFAULT);
specialDatePaint = new Paint();
specialDatePaint.setColor(textColor);
specialDatePaint.setAntiAlias(true);
specialDatePaint.setTextSize(CommUtil.getRawSize(getContext(), TypedValue.COMPLEX_UNIT_SP, cellTextSize));
specialDatePaint.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD_ITALIC));
boxPath = new Path();
//boxPath.addRect(0, 0, width, height, Direction.CW);
//boxPath.moveTo(0, monthHeight);
boxPath.rLineTo(width, 0);
boxPath.moveTo(0, monthHeight + weekHeight);
boxPath.rLineTo(width, 0);
for (int i = 1; i < 7; i++) {
boxPath.moveTo(0, monthHeight + weekHeight + i * cellHeight);
boxPath.rLineTo(width, 0);
boxPath.moveTo(i * cellWidth, monthHeight);
boxPath.rLineTo(0, height - monthHeight);
}
// boxPath.moveTo(6 * cellWidth, monthHeight);
// boxPath.rLineTo(0, height - monthHeight);
//preMonthBtnPath = new Path();
//int btnHeight = (int) (monthHeight * 0.6f);
//preMonthBtnPath.moveTo(monthChangeWidth / 2f, monthHeight / 2f);
//preMonthBtnPath.rLineTo(btnHeight / 2f, -btnHeight / 2f);
//preMonthBtnPath.rLineTo(0, btnHeight);
//preMonthBtnPath.close();
//nextMonthBtnPath = new Path();
//nextMonthBtnPath.moveTo(width - monthChangeWidth / 2f,
// monthHeight / 2f);
//nextMonthBtnPath.rLineTo(-btnHeight / 2f, -btnHeight / 2f);
//nextMonthBtnPath.rLineTo(0, btnHeight);
//nextMonthBtnPath.close();
monthChangeBtnPaint = new Paint();
monthChangeBtnPaint.setAntiAlias(true);
monthChangeBtnPaint.setStyle(Paint.Style.FILL_AND_STROKE);
monthChangeBtnPaint.setColor(btnColor);
cellBgPaint = new Paint();
cellBgPaint.setAntiAlias(true);
cellBgPaint.setStyle(Paint.Style.FILL);
cellBgPaint.setColor(cellSelectedColor);
}
/**
* Converts an arc to cubic Bezier segments and records them in p.
*
* @param p
* The target for the cubic Bezier segments
* @param cx
* The x coordinate center of the ellipse
* @param cy
* The y coordinate center of the ellipse
* @param a
* The radius of the ellipse in the horizontal direction
* @param b
* The radius of the ellipse in the vertical direction
* @param e1x
* E(eta1) x coordinate of the starting point of the arc
* @param e1y
* E(eta2) y coordinate of the starting point of the arc
* @param theta
* The angle that the ellipse bounding rectangle makes with horizontal plane
* @param start
* The start angle of the arc on the ellipse
* @param sweep
* The angle (positive or negative) of the sweep of the arc on the ellipse
*/
private static void arcToBezier(Path p,
double cx,
double cy,
double a,
double b,
double e1x,
double e1y,
double theta,
double start,
double sweep) {
// Taken from equations at: http://spaceroots.org/documents/ellipse/node8.html
// and http://www.spaceroots.org/documents/ellipse/node22.html
// Maximum of 45 degrees per cubic Bezier segment
int numSegments = (int) Math.ceil(Math.abs(sweep * 4 / Math.PI));
double eta1 = start;
double cosTheta = Math.cos(theta);
double sinTheta = Math.sin(theta);
double cosEta1 = Math.cos(eta1);
double sinEta1 = Math.sin(eta1);
double ep1x = (-a * cosTheta * sinEta1) - (b * sinTheta * cosEta1);
double ep1y = (-a * sinTheta * sinEta1) + (b * cosTheta * cosEta1);
double anglePerSegment = sweep / numSegments;
for (int i = 0; i < numSegments; i++) {
double eta2 = eta1 + anglePerSegment;
double sinEta2 = Math.sin(eta2);
double cosEta2 = Math.cos(eta2);
double e2x = cx + (a * cosTheta * cosEta2) - (b * sinTheta * sinEta2);
double e2y = cy + (a * sinTheta * cosEta2) + (b * cosTheta * sinEta2);
double ep2x = -a * cosTheta * sinEta2 - b * sinTheta * cosEta2;
double ep2y = -a * sinTheta * sinEta2 + b * cosTheta * cosEta2;
double tanDiff2 = Math.tan((eta2 - eta1) / 2);
double alpha =
Math.sin(eta2 - eta1) * (Math.sqrt(4 + (3 * tanDiff2 * tanDiff2)) - 1) / 3;
double q1x = e1x + alpha * ep1x;
double q1y = e1y + alpha * ep1y;
double q2x = e2x - alpha * ep2x;
double q2y = e2y - alpha * ep2y;
// Adding this no-op call to workaround a proguard related issue.
p.rLineTo(0, 0);
p.cubicTo((float) q1x,
(float) q1y,
(float) q2x,
(float) q2y,
(float) e2x,
(float) e2y);
eta1 = eta2;
e1x = e2x;
e1y = e2y;
ep1x = ep2x;
ep1y = ep2y;
}
}