我在画布上有两个点,现在我可以使用
在这些点之间绘制一条线,如下图所示此代码canvas.drawLine(p1.x, p1.y, p2.x, p2.y, paint);
我想在两个点之间绘制弧线,如下图所示。
我怎么画这样。
答案 0 :(得分:46)
最后我从这段代码中得到了解决方案:
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
表示您要开始绘制Arc的位置。 sweepAngle
表示两条线之间的角度。我们必须通过使用两个点来计算它,比如我的问题图像中的蓝点。
答案 1 :(得分:18)
做这样的事情:
@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);
}
答案 2 :(得分:4)
我试图做一些与众不同的事情,而且都是关于计算扫描和开始角度的。
我希望显示一个圆弧,表示从上到下的圆圈上的进度。
所以我从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.
答案 3 :(得分:0)
绘制弧的样本。
from jsonpath_ng.ext import parse
abilityname = "device_info"
propertyname = "manufacturer"
result = parse('$[?(@.name=="' + abilityname + '")].properties[?(@.name=="' + propertyname + '")]').find(myJson)
if len(result) == 1:
return str(result[0].value['value'])
else:
return ""
答案 4 :(得分:0)
Langkiller提出了here一个简单的解决方案。从起点到控制点到终点画一条三次线。
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)
答案 5 :(得分:0)
我可能来晚了,但我得到了更多信息。
Android Lollipop
之后,有两种方法可以解决此问题
public void drawArc(RectF椭圆形,float startAngle,float sweepAngle, 布尔useCenter,油漆)
public void drawArc(向左浮动,向顶部浮动,向右浮动,向下方浮动, float startAngle,float sweepAngle,boolean useCenter,Paint paint)
用法:
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;
}
}
完整的源代码:
答案 6 :(得分:0)
首先,我们需要从起始角度和后掠角度视觉化坐标,然后它将变得更加清晰。
因此,如果您只想要圆的右上角,我们可以做这样的事情:
2N*2N
..
从270度开始(按照上图,向前“倾斜” 90度。您将得到以下形状:
再创建一个,这样您就可以掌握它了。这次让我们使用负值:我们要从右侧开始创建半月形(弧):
val rect = RectF(0f, 0f, 500f, 300f)
val paint = Paint()
paint.apply {
strokeWidth = 5f
setStyle(Paint.Style.STROKE)
color = COLOR.BLUE
}
path.addArc(rect, 270f, 90f)
在这里,我们从0开始并“扫过” -180度。 结果是: