我正在将Skycons移植到Android上,我的大部分都在工作,除了月亮使用带有逆时针参数的HTML5 Canvas.arc
。
我试图这样实现:
RectF rect = new RectF();
public void arcR( Path path, float x, float y, float radius, double startAngle, double endAngle, boolean anticlockwise ){
// Set bounds
rect.set( x - radius, y - radius, x + radius, y + radius );
// Convert to degrees
startAngle = Math.toDegrees(startAngle);
endAngle = Math.toDegrees(endAngle);
if(anticlockwise){
startAngle = 360 - startAngle;
endAngle = 360 - endAngle;
}
endAngle = endAngle - startAngle;
path.addArc(rect, (float)startAngle, (float)endAngle);
}
我认为我没有正确实施逆时针,因为在我的设备上绘制月球(基于Skycons)看起来像这样:
答案 0 :(得分:5)
对于逆时针弧,扫掠角需要为负
float sweepAngle = ((endAngle + 360) - startAngle) % 360;
if (anticlockwise) {
sweepAngle = sweepAngle - 360;
}
path.addArc(rect, startAngle, sweepAngle);
答案 1 :(得分:0)
double sweepAngle = endAngle - startAngle;
startAngle = 360 - endAngle;
path.addArc(rect, (float)startAngle, (float)sweepAngle);
答案 2 :(得分:0)
要绘制一条剪切线,您需要找到第二个圆的中心。我假设切口圆半径与原始圆相同,但当然你可以改变它。
请尝试以下代码:
private void drawMoon(Path path, float x, float y, float radius, float startAngle, float endAngle) {
float sweepAngle = endAngle - startAngle;
float x1 = (float) (x + radius * Math.cos(Math.toRadians(startAngle)));
float y1 = (float) (y + radius * Math.sin(Math.toRadians(startAngle)));
float x2 = (float) (x + radius * Math.cos(Math.toRadians(endAngle)));
float y2 = (float) (y + radius * Math.sin(Math.toRadians(endAngle)));
float x3 = (x1 + x2) / 2;
float y3 = (y1 + y2) / 2;
float q = (float) Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
float r = radius; // cutout circle radius
float cx = (float) (x3 + Math.sqrt(r * r - (q / 2) * (q / 2)) * (y1 - y2) / q);
float cy = (float) (y3 + Math.sqrt(r * r - (q / 2) * (q / 2)) * (x2 - x1) / q);
path.rewind();
rect.set(x - radius, y - radius, x + radius, y + radius);
path.addArc(rect, startAngle, sweepAngle);
rect.set(cx - r, cy - r, cx + r, cy + r);
path.addArc(rect, (float) Math.toDegrees(Math.atan2(y1 - cy, x1 - cx)), 360 - sweepAngle);
}
答案 3 :(得分:0)
html5 canvas arc和android canvas arc之间的区别:
在html5 / javascript中你将centerX,centerY,radius作为前3个参数。在android中,你给出了围绕圆圈而不是那些3的矩形。这对圆圈来说有点麻烦,但更灵活,因为你也可以做椭圆(椭圆)
在javascript中,您将逆时针的起始角度,结束角度和布尔值作为参数4,5,6。在android中,你给出了起始角度和“扫掠角度”。 “扫掠角”是端角和起始角之间的差。如果你想要逆时针,只需给出负扫描角度。
javascript角度是弧度,在android中它们是度数。
作为一个例子,这里有一些示例代码,它绘制一个C形图形,左边是一个长弧,右边是3个短弧,其中一个是逆时针。
JavaScript的:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="content-type" content="text/html" />
<title>arcs</title>
<script type="text/javascript">
function initPage(){
ctx = document.getElementById("canvas").getContext('2d');
ctx.fillStyle = "blue";
pi = Math.PI;
r = 100;
R = 3 * r;
padding = 5;
width = 2 * (R + padding);
height = width;
centerX = padding + width/2;
centerY = padding + height/2;
ctx.beginPath();
ctx.arc(centerX, centerY, R, pi/2, 3*pi/2, false);
ctx.arc(centerX, centerY - 2*r, r, 3*pi/2, pi/2, false);
ctx.arc(centerX, centerY, r, 3*pi/2, pi/2, true );
ctx.arc(centerX, centerY + 2*r, r, 3*pi/2, pi/2, false);
ctx.fill();
}
</script>
</head>
<body onload="initPage();">
<canvas id="canvas" width="610" height="610"></canvas>
</body>
</html>
机器人:
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.widget.ImageView;
public class MainActivity extends Activity {
private void drawToImageView(ImageView iv){
Paint paint = new Paint();
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.BLUE);
Path path = new Path();
int radius = 140;
int Radius = 3 * radius;
int padding = 5;
int width = 2 * (Radius + padding);
int height = width;
Bitmap bm = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bm);
float a = 90f;
float b = 3*a;
float pi = 2*a;
float _radius = (float)radius;
float _Radius = (float)Radius;
float centerX = padding + width/2;
float centerY = padding + height/2;
path.addArc(circRect(centerX, centerY, _Radius), a, pi);
path.addArc(circRect(centerX, centerY - 2*_radius, _radius), b, pi);
path.addArc(circRect(centerX, centerY, _radius), b, -pi);
path.addArc(circRect(centerX, centerY + 2*_radius, _radius), b, pi);
canvas.drawPath(path, paint);
iv.setImageDrawable(new BitmapDrawable(getResources(), bm));
}
private RectF circRect(float centerX, float centerY, float radius){
float left = centerX - radius;
float right = centerX + radius;
float top = centerY - radius;
float bottom = centerY + radius;
return new RectF(left, top, right, bottom);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ImageView iv = (ImageView)findViewById(R.id.myImageView);
drawToImageView(iv);
}
}