我很难解决这个问题,我发现了与三角学的交易,这是我没有经验的问题。我需要创建这样的视图:提出的图形。我有弧线和主量规的背景图像,但我需要添加您看到的时间标记,包括形状和时代。由于标记的数量可以从1到28,但需要以编程方式添加它们,尽管可能不超过10个。
我已经尝试使用扫角来获取弧线的x/y位置(使用除法来定义增加的扫角角度以增加弧线),并且它适用于第一个,但我无法做到为具有不同扫角角度的其他任何一个复制。我还使用矩阵来旋转或多或少有效的标记图像,我一直在尝试各种trig函数以获取x和y。以下是一些代码:基本代码:
public class Custom_clock extends View
{
private Paint mPaint;
private RectF rectF;
private int mStrokeWidth;
private int width;
private int height;
private Typeface custom_font;
private final int MAX = 263;
private final int START = 138;
private Bitmap bitmap;
private Bitmap marker;
private int scaledSizeNumbers;
private int scaledSizeLabels;
private int scaledSizeDose;
private Matrix matrix = new Matrix();
private String hoursMinsLabel = "Minutes";
private String hoursMinsNumber = "3";
private ArrayList<String>DoseTimes = new ArrayList<>();
public Custom_clock(Context context)
{
super(context);
}
public Custom_clock(Context context, AttributeSet attrs) {
super(context, attrs);
}
public Custom_clock(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
private void initClock(){
width = getWidth();
height = getHeight();
mStrokeWidth = ((width+height)/33);
custom_font = Typeface.createFromAsset(getResources().getAssets(), "fonts/text_font.ttf");
bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.base_arc3);
marker = BitmapFactory.decodeResource(getResources(), R.drawable.single_marker);
scaledSizeNumbers = getResources().getDimensionPixelSize(R.dimen.NumberFontSize);
scaledSizeLabels = getResources().getDimensionPixelSize(R.dimen.LabelFontSize);
scaledSizeDose = getResources().getDimensionPixelSize(R.dimen.DoseFontSize);
int scaledMarginWidth = getResources().getDimensionPixelSize(R.dimen.WidthMargin);
int scaledMarginTop = getResources().getDimensionPixelSize(R.dimen.TopMargin);
mPaint = new Paint();
rectF = new RectF(scaledMarginWidth,scaledMarginTop,getWidth()- scaledMarginWidth,getHeight());
DoseTimes.clear();
DoseTimes.add("1:00pm");
DoseTimes.add("2:00pm");
DoseTimes.add("3:00pm");
DoseTimes.add("4:00pm");
DoseTimes.add("5:00pm");
}
private void DrawMainArc(Canvas canvas){
Paint paint =new Paint();
initClock();
canvas.drawBitmap(bitmap,null,rectF,paint);
mPaint.setColor(getResources().getColor(R.color.light_grey));
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(mStrokeWidth+2);
mPaint.setStrokeCap(Paint.Cap.ROUND);
canvas.drawArc(rectF,START,GetStops(5,MAX)*2,false, mPaint);
}
private int GetStops(int stops, int max){
return max/stops;
}
@Override
protected void onDraw(Canvas canvas)
{
if(bitmap != null){
super.onDraw(canvas);
DrawMainArc(canvas);
DrawOutlineArc(canvas);
DrawHours(canvas);
DrawHoursLabel(canvas);
DrawDoseLabel(canvas);
AddStops(canvas);
}
}
标记特定代码尝试:这吸引了第一个标记物相当接近我想要的位置,但其余的标记逐渐绘制,越来越多地向左绘制,只有2个甚至可见。我知道答案在某个角度,可能是矩阵,但触发了我。
private void AddStops(Canvas canvas){
int stopsNum = DoseTimes.size();//currently 5
int rotatinalIncrement = MAX/(stopsNum);//currently 54
int markerAngle = 0;
double x;
double y;
for(int i =0; i <stopsNum; i++){
x = (canvas.getWidth()/4) * Math.cos(markerAngle);
y = (canvas.getWidth()/4) * Math.cos(markerAngle);
markerAngle = markerAngle +rotatinalIncrement;
DrawMarker(canvas,markerAngle,(int)x ,(int)y);
}
}
private void DrawMarker(Canvas canvas, int Angle, int x, int y){
int scaledSize = getResources().getDimensionPixelSize(R.dimen.MarkerSize);
Bitmap scaled = Bitmap.createScaledBitmap(marker,scaledSize,scaledSize,false);
matrix.reset();
matrix.postTranslate(-canvas.getWidth() / 2, -canvas.getHeight() / 2); // Centers image
matrix.postRotate(angle);
matrix.setRotate(Angle);
matrix.postTranslate(x, y);
canvas.drawBitmap(scaled, matrix, null);
}
首先, Math.cos
和 sin
在弧度中使用参数,而您(似乎来自Value 54的看来)将参数以度应用。只需在JavaScript中存在markerAngle * Math.Pi / 180
或使用toRadians
的函数。
第二 - 对于y坐标,您必须使用sin
而不是cos