我在画布上有两个点,现在我能够通过使用绘制这些点之间这样一行下面的图片
此代码canvas.drawLine(p1.x, p1.y, p2.x, p2.y, paint);
我想提请两点像下面的图像之间的电弧。
我怎样才能画出这样。
我在画布上有两个点,现在我能够通过使用绘制这些点之间这样一行下面的图片
此代码canvas.drawLine(p1.x, p1.y, p2.x, p2.y, paint);
我想提请两点像下面的图像之间的电弧。
我怎样才能画出这样。
最后,我从这个代码的解决方案:
float radius = 20;
final RectF oval = new RectF();
oval.set(point1.x - radius, point1.y - radius, point1.x + radius, point1.y+ radius);
Path myPath = new Path();
myPath.arcTo(oval, startAngle, -(float) sweepAngle, true);
要计算startAngle
,使用此代码:
int startAngle = (int) (180 / Math.PI * Math.atan2(point.y - point1.y, point.x - point1.x));
在这里, point1
表示要开始绘制弧。 sweepAngle
意味着两条线之间的角度。 我们必须通过使用两个点像我的问题像蓝色的点来计算。
做这样的事情:
@Override
protected void onDraw(Canvas canvas) {
Paint p = new Paint();
RectF rectF = new RectF(50, 20, 100, 80);
p.setColor(Color.BLACK);
canvas.drawArc (rectF, 90, 45, true, p);
}
我试图做的东西有点不同,它是所有关于计算扫描和启动角。
我想表明,代表了从顶部进入底部的圆进步的弧。
所以,我从0至100有进步价值,我想表明,从顶部开始底部填充圈当进度为100的弧。
要计算我用的是sweepAngle:
int sweepAngle = (int) (360 * (getProgress() / 100.f));
其次是计算由startAngle
int startAngle = 270 - sweepAngle / 2;
起始角的计算这种方式,因为:
因此,考虑到我有25%的进步
sweepAngle = 90 degrees (90 degrees is quarter of a circle)
start angle = 225 (45 degrees away from 270)
如果你想进步,从其他侧面去(从左到右,从右到左等),你只需要根据原料的角度,以取代270。
对于平局弧的样本。
public static Bitmap clipRoundedCorner(Bitmap bitmap, float r, boolean tr, boolean tl, boolean bl, boolean br)
{
int W = bitmap.getWidth();
int H = bitmap.getHeight();
if (r < 0)
r = 0;
int smallLeg = W;
if(H < W )
smallLeg = H;
if (r > smallLeg)
r = smallLeg / 2;
float lineStop = r/2;
Path path = new Path();
path.moveTo(0,0);
if(tr)
{
path.moveTo(0, lineStop);
path.arcTo(new RectF(0,0, r,r), 180, 90, false);
}
path.lineTo(W-lineStop, 0);
if(tl)
path.arcTo(new RectF(W-r,0, W,r), 270, 90, false);
else
path.lineTo(W, 0);
path.lineTo(W, H-lineStop);
if(bl)
path.arcTo(new RectF(W-r,H-r, W,H), 0, 90, false);
else
path.lineTo(W, H);
path.lineTo(lineStop, H);
if(br)
path.arcTo(new RectF(0,H-r, r,H), 90, 90, false);
else
path.lineTo(0,H);
if(tr)
path.lineTo(0,lineStop);
else
path.lineTo(0,0);
Bitmap output = Bitmap.createBitmap(W, H, Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(Color.BLACK);
canvas.drawPath(path, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(bitmap, 0, 0, paint);
return output;
}
一个简单的解决方案建议在这里通过Langkiller。 这就使人们从经由控制点到结束点的开始点的立方线。
Path path = new Path();
float startX = 0;
float startY = 2;
float controlX = 2;
float controlY = 4;
float endX = 4
float endY = 2
conePath.cubicTo(startX, startY, controlX, controlY,endX, endY);
Paint paint = new Paint();
paint.setARGB(200, 62, 90, 177);
paint.setStyle(Paint.Style.FILL);
canvas.drawPath(path, paint)
我可能会迟到回答,但我得到了更多的信息。
之后Android Lollipop
有解决这个问题的两种方法
公共无效drawArc(RectF椭圆形,浮startAngle开始,浮sweepAngle,布尔useCenter,涂料粉刷)
公共无效drawArc(左浮动,最高上浮,上浮右,底部浮动,浮动由startAngle,浮sweepAngle,布尔useCenter,涂料粉刷)
用法:
RectF rectF = new RectF(left, top, right, bottom);
// method 1
canvas.drawArc (rectF, 90, 45, true, paints[0]);
// method 2
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
canvas.drawArc (left, top, right, bottom, 0, 45, true, paints[1]);
}
后掠角无非是被吸入顺时针如部门的角度更大。 下面的代码
private void drawArcs(Canvas canvas) {
RectF rectF = new RectF(left, top, right, bottom);
// white arc
canvas.drawArc (rectF, 90, 45, true, paints[0]);
// Green arc
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
canvas.drawArc (left, top, right, bottom, 0, 45, true, paints[1]);
}
// Red stroked arc
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
canvas.drawArc (left, top, right, bottom, 180, 45, true, paints[2]);
}
}
结果会是这样的
同样可以定义路径,然后遍历它们的onDraw方法,在这个片段中所示的帮助来实现:
public class ArcDrawable extends Drawable {
private int left, right, top, bottom;
private Paint[] paints = new Paint[3];
private HashMap<Path, Paint> pathMap = new HashMap();
public ArcDrawable() {
// white paint
Paint whitePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
whitePaint.setColor(Color.WHITE);
paints[0]= whitePaint;
// green paint
Paint greenPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
greenPaint.setColor(Color.GREEN);
paints[1]= greenPaint;
// red paint
Paint redPaint =new Paint(Paint.ANTI_ALIAS_FLAG);
redPaint.setColor(Color.RED);
redPaint.setStyle(Paint.Style.STROKE);
paints[2]= redPaint;
}
@Override
public void draw(Canvas canvas) {
//----------USE PATHS----------
// Define and use custom Path
for (Map.Entry<Path, Paint> entry : pathMap.entrySet()) {
// Draw Path on respective Paint style
canvas.drawPath(entry.getKey(), entry.getValue());
}
// -------OR use conventional Style---------
//drawArcs(canvas);
}
//Same result
private void drawArcs(Canvas canvas) {
RectF rectF = new RectF(left, top, right, bottom);
// method 1
canvas.drawArc (rectF, 90, 45, true, paints[0]);
// method 2
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
canvas.drawArc (left, top, right, bottom, 0, 45, true, paints[1]);
}
// method two with stroke
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
canvas.drawArc (left, top, right, bottom, 180, 45, true, paints[2]);
}
}
@Override
protected void onBoundsChange(Rect bounds) {
super.onBoundsChange(bounds);
int width = bounds.width();
int height = bounds.height();
left = bounds.left;
right = bounds.right;
top = bounds.top;
bottom = bounds.bottom;
final int size = Math.min(width, height);
final int centerX = bounds.left + (width / 2);
final int centerY = bounds.top + (height / 2);
pathMap.clear();
//update pathmap using new bounds
recreatePathMap(size, centerX, centerY);
invalidateSelf();
}
private Path recreatePathMap(int size, int centerX, int centerY) {
RectF rectF = new RectF(left, top, right, bottom);
// first arc
Path arcPath = new Path();
arcPath.moveTo(centerX,centerY);
arcPath.arcTo (rectF, 90, 45);
arcPath.close();
// add to draw Map
pathMap.put(arcPath, paints[0]);
//second arc
arcPath = new Path();
arcPath.moveTo(centerX,centerY);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
arcPath.arcTo (rectF, 0, 45);
}
arcPath.close();
// add to draw Map
pathMap.put(arcPath, paints[1]);
// third arc
arcPath = new Path();
arcPath.moveTo(centerX,centerY);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
arcPath.arcTo (rectF, 180, 45);
}
arcPath.close();
// add to draw Map
pathMap.put(arcPath, paints[2]);
return arcPath;
}
@Override
public void setAlpha(int alpha) {
}
@Override
public void setColorFilter(@Nullable ColorFilter colorFilter) {
}
@Override
public int getOpacity() {
return 0;
}
}
完整的源代码:
https://github.com/hiteshsahu/Arc-Drawable