List of usage examples for android.graphics Path Path
public Path()
From source file:com.fjoglar.etsitnoticias.view.widget.InkPageIndicator.java
public InkPageIndicator(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); final int density = (int) context.getResources().getDisplayMetrics().density; // Load attributes final TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.InkPageIndicator, defStyle, 0); dotDiameter = a.getDimensionPixelSize(R.styleable.InkPageIndicator_dotDiameter, DEFAULT_DOT_SIZE * density); dotRadius = dotDiameter / 2;/*from w w w . j av a2s.c o m*/ halfDotRadius = dotRadius / 2; gap = a.getDimensionPixelSize(R.styleable.InkPageIndicator_dotGap, DEFAULT_GAP * density); animDuration = (long) a.getInteger(R.styleable.InkPageIndicator_animationDuration, DEFAULT_ANIM_DURATION); animHalfDuration = animDuration / 2; unselectedColour = a.getColor(R.styleable.InkPageIndicator_pageIndicatorColor, DEFAULT_UNSELECTED_COLOUR); selectedColour = a.getColor(R.styleable.InkPageIndicator_currentPageIndicatorColor, DEFAULT_SELECTED_COLOUR); a.recycle(); unselectedPaint = new Paint(Paint.ANTI_ALIAS_FLAG); unselectedPaint.setColor(unselectedColour); selectedPaint = new Paint(Paint.ANTI_ALIAS_FLAG); selectedPaint.setColor(selectedColour); if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) { interpolator = AnimUtils.getFastOutSlowInInterpolator(context); } else { interpolator = null; } // create paths & rect now reuse & rewind later combinedUnselectedPath = new Path(); unselectedDotPath = new Path(); unselectedDotLeftPath = new Path(); unselectedDotRightPath = new Path(); rectF = new RectF(); addOnAttachStateChangeListener(this); }
From source file:org.goodev.material.widget.InkPageIndicator.java
public InkPageIndicator(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); final int density = (int) context.getResources().getDisplayMetrics().density; // Load attributes final TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.InkPageIndicator, defStyle, 0); dotDiameter = a.getDimensionPixelSize(R.styleable.InkPageIndicator_dotDiameter, DEFAULT_DOT_SIZE * density); dotRadius = dotDiameter / 2;//from ww w . ja v a2 s.co m halfDotRadius = dotRadius / 2; gap = a.getDimensionPixelSize(R.styleable.InkPageIndicator_dotGap, DEFAULT_GAP * density); animDuration = (long) a.getInteger(R.styleable.InkPageIndicator_animationDuration, DEFAULT_ANIM_DURATION); animHalfDuration = animDuration / 2; unselectedColour = a.getColor(R.styleable.InkPageIndicator_pageIndicatorColor, DEFAULT_UNSELECTED_COLOUR); selectedColour = a.getColor(R.styleable.InkPageIndicator_currentPageIndicatorColor, DEFAULT_SELECTED_COLOUR); a.recycle(); unselectedPaint = new Paint(Paint.ANTI_ALIAS_FLAG); unselectedPaint.setColor(unselectedColour); selectedPaint = new Paint(Paint.ANTI_ALIAS_FLAG); selectedPaint.setColor(selectedColour); if (UI.isLollipop()) { interpolator = android.view.animation.AnimationUtils.loadInterpolator(context, android.R.interpolator.fast_out_slow_in); } else { interpolator = android.view.animation.AnimationUtils.loadInterpolator(context, android.R.interpolator.accelerate_decelerate); } // create paths & rect now reuse & rewind later combinedUnselectedPath = new Path(); unselectedDotPath = new Path(); unselectedDotLeftPath = new Path(); unselectedDotRightPath = new Path(); rectF = new RectF(); addOnAttachStateChangeListener(this); }
From source file:de.hs_bremen.aurora_hunter.ui.views.PredictionGraphView.java
public void onDraw(Canvas canvas) { if (mPoints.size() == 0) { return;// w ww. j a v a 2s . co m } int yOffsetForLabels = 0; if (mMax * mScaleFactor > 0.8) { yOffsetForLabels = 15; } Path path = new Path(); int height = canvas.getHeight(); int width = canvas.getWidth(); for (Point point : mPoints) { point.x = point.percentageX * width + 60; // Log.i("mScaleFactor", " : " + mScaleFactor); //Log.i("percent", " : " + percent); point.y = (float) ((1 - point.percentageY * mScaleFactor) * height) + yOffsetForLabels * 3; } if (mPoints.size() > 1) { //calcuate x/y based on size of canvas for (int i = 0; i < mPoints.size(); i++) { if (i >= 0) { Point point = mPoints.get(i); // Log.i("dx",point.x + " - " + point.y ); if (i == 0) { Point next = mPoints.get(i + 1); point.dx = ((next.x - point.x) / 5); point.dy = ((next.y - point.y) / 5); } else if (i == mPoints.size() - 1) { Point prev = mPoints.get(i - 1); point.dx = ((point.x - prev.x) / 5); point.dy = ((point.y - prev.y) / 5); } else { Point next = mPoints.get(i + 1); Point prev = mPoints.get(i - 1); point.dx = ((next.x - prev.x) / 5); point.dy = ((next.y - prev.y) / 5); } } } } if (mPoints.size() > 0) { path.moveTo(0, (float) (canvas.getHeight() * 0.8)); path.lineTo(0, mPoints.get(0).y); } boolean first = true; for (int i = 0; i < mPoints.size(); i++) { Point point = mPoints.get(i); if (first) { first = false; path.cubicTo(point.x - point.x * 2, point.y - point.y / 5, point.x - point.dx, point.y - point.dy, point.x, point.y); } else { Point prev = mPoints.get(i - 1); // Log.i("Draw", point.dx + " " + point.dy); path.cubicTo(prev.x + prev.dx, prev.y + prev.dy, point.x - point.dx, point.y - point.dy, point.x, point.y); } } if (mPoints.size() > 0) { path.lineTo(width, mPoints.get(mPoints.size() - 1).y); } path.lineTo(width, height); path.lineTo(0, height); canvas.drawPath(path, mGraphPaint); int detlaY = 30; for (Point p : mPoints) { int val = (int) Math.round(p.percentageY * 100); //if last element if (mPoints.indexOf(p) == mPoints.size() - 1) { //Log.i("last", p.toString()); if (val == 0 || p.y > getHeight()) { canvas.drawText(val + "%", p.x - 150, getHeight() - detlaY, mTextPaint); } else { canvas.drawText(val + "%", p.x - 150, p.y - detlaY + yOffsetForLabels, mTextPaint); } } else { if (val == 0 || p.y > getHeight()) { canvas.drawText(val + "%", p.x - 20, getHeight() - detlaY, mTextPaint); } else { canvas.drawText(val + "%", p.x - 20, p.y - detlaY + yOffsetForLabels, mTextPaint); } } //Log.i("point", p.toString()); } // Log.i("Lenght", mPoints.size() + " "); float levelStart = (float) (canvas.getHeight() - (mNotificationLevel * canvas.getHeight())); float lineHeight = DpToPixelUtil.convertDpToPixel(2, getContext()); if (mViewMode == PredictionFragment.NOTIFICATION_MODE.SET_NOTIFICATION_LEVEL) { mNotificationLevelPaint.setAlpha(150); float leftOffset = 0; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { float arcHeight = DpToPixelUtil.convertDpToPixel(30, getContext()); leftOffset = arcHeight; RectF rectF = new RectF(getWidth() - arcHeight, levelStart - arcHeight / 2, getWidth(), levelStart + arcHeight / 2); canvas.drawArc(rectF, 0, 360, true, mNotificationLevelPaint); } canvas.drawRect(0, levelStart, canvas.getWidth() - leftOffset, levelStart + lineHeight, mNotificationLevelPaint); mNotificationLevelPaint.setAlpha(20); canvas.drawRect(0, levelStart + lineHeight, canvas.getWidth(), canvas.getHeight(), mNotificationLevelPaint); String text = Math.round(mNotificationLevel * 100) + "%"; canvas.drawText(text, DpToPixelUtil.convertDpToPixel(10, getContext()), levelStart + DpToPixelUtil.convertDpToPixel(25, getContext()), mNotificationLevelTextPaint); } else { mNotificationLevelPaint.setAlpha(30); canvas.drawRect(0, levelStart, canvas.getWidth(), levelStart + lineHeight, mNotificationLevelPaint); } }
From source file:ee.ioc.phon.android.speak.Utils.java
static Bitmap bytesToBitmap(byte[] byteBuffer, int w, int h, int startPosition, int endPosition) { final ShortBuffer waveBuffer = ByteBuffer.wrap(byteBuffer).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer(); final Bitmap b = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); final Canvas c = new Canvas(b); final Paint paint = new Paint(); paint.setColor(0xFFFFFFFF); // 0xAARRGGBB paint.setAntiAlias(true);//w w w. j a va2s . c o m paint.setStyle(Paint.Style.STROKE); paint.setAlpha(80); final PathEffect effect = new CornerPathEffect(3); paint.setPathEffect(effect); final int numSamples = waveBuffer.remaining(); int endIndex; if (endPosition == 0) { endIndex = numSamples; } else { endIndex = Math.min(endPosition, numSamples); } int startIndex = startPosition - 2000; // include 250ms before speech if (startIndex < 0) { startIndex = 0; } final int numSamplePerWave = 200; // 8KHz 25ms = 200 samples final float scale = 10.0f / 65536.0f; final int count = (endIndex - startIndex) / numSamplePerWave; final float deltaX = 1.0f * w / count; int yMax = h / 2; Path path = new Path(); c.translate(0, yMax); float x = 0; path.moveTo(x, 0); for (int i = 0; i < count; i++) { final int avabs = getAverageAbs(waveBuffer, startIndex, i, numSamplePerWave); int sign = ((i & 01) == 0) ? -1 : 1; final float y = Math.min(yMax, avabs * h * scale) * sign; path.lineTo(x, y); x += deltaX; path.lineTo(x, y); } if (deltaX > 4) { paint.setStrokeWidth(2); } else { paint.setStrokeWidth(Math.max(0, (int) (deltaX - .05))); } c.drawPath(path, paint); return b; }
From source file:com.lovejjfg.arsenal.ui.widget.JumpBall.java
private void init() { if (mPaint == null) { mPaint = new Paint(); mPaint.setAntiAlias(true);/*from w w w. j a v a2 s .com*/ mPaint.setColor(ContextCompat.getColor(getContext(), R.color.colorAccent)); mPaint.setStyle(Paint.Style.FILL_AND_STROKE); } if (mPath == null) { mPath = new Path(); } pullAnimator = ValueAnimator.ofInt(0, pullRange, 0); pullAnimator.setDuration((long) (dropTime * 0.5f)); pullAnimator.addUpdateListener(animation -> { mChange = (Integer) animation.getAnimatedValue(); if (animation.getAnimatedFraction() > 0.3) { dropAnimator.setIntValues(dropHeight, 0, dropHeight); dropAnimator.setDuration(dropTime * 2); dropAnimator.start(); } Log.e("TAG", "onAnimationUpdate: " + mChange); invalidate(); }); pullAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { } }); dropAnimator = ValueAnimator.ofInt(0, dropHeight); // dropAnimator.setRepeatMode(ValueAnimator.REVERSE); // dropAnimator.setRepeatCount(20); dropAnimator.setDuration(dropTime); dropAnimator.setInterpolator(new LinearInterpolator()); dropAnimator.addUpdateListener(animation -> { mTranslateValue = (Integer) animation.getAnimatedValue(); invalidate(); }); dropAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { // dropAnimator = ValueAnimator.ofInt(dropHeight, 0, dropHeight); pullAnimator.start(); } }); dropAnimator.start(); radioAnimator = ValueAnimator.ofFloat(mCircleRadius, mWidth); // radioAnimator.setRepeatMode(ValueAnimator.REVERSE); // radioAnimator.setRepeatCount(20); radioAnimator.setDuration(600); radioAnimator.setInterpolator(new LinearInterpolator()); radioAnimator.addUpdateListener(animation -> { mCurrentRadio = (float) animation.getAnimatedValue(); invalidate(); }); radioAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationStart(Animator animation) { super.onAnimationStart(animation); pullAnimator.cancel(); dropAnimator.cancel(); } @Override public void onAnimationEnd(Animator animation) { isEnd = false; mCurrentRadio = mCircleRadius; if (dismissListener != null) { dismissListener.onDismiss(); } setVisibility(GONE); } }); // radioAnimator.start(); }
From source file:com.android.settings.widget.DotsPageIndicator.java
public DotsPageIndicator(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); final int scaledDensity = (int) context.getResources().getDisplayMetrics().scaledDensity; // Load attributes final TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.DotsPageIndicator, defStyle, 0);/*from ww w. ja v a2 s . c o m*/ dotDiameter = typedArray.getDimensionPixelSize(R.styleable.DotsPageIndicator_dotDiameter, DEFAULT_DOT_SIZE * scaledDensity); dotRadius = dotDiameter / 2; halfDotRadius = dotRadius / 2; gap = typedArray.getDimensionPixelSize(R.styleable.DotsPageIndicator_dotGap, DEFAULT_GAP * scaledDensity); animDuration = (long) typedArray.getInteger(R.styleable.DotsPageIndicator_animationDuration, DEFAULT_ANIM_DURATION); animHalfDuration = animDuration / 2; unselectedColour = typedArray.getColor(R.styleable.DotsPageIndicator_pageIndicatorColor, DEFAULT_UNSELECTED_COLOUR); selectedColour = typedArray.getColor(R.styleable.DotsPageIndicator_currentPageIndicatorColor, DEFAULT_SELECTED_COLOUR); typedArray.recycle(); unselectedPaint = new Paint(Paint.ANTI_ALIAS_FLAG); unselectedPaint.setColor(unselectedColour); selectedPaint = new Paint(Paint.ANTI_ALIAS_FLAG); selectedPaint.setColor(selectedColour); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { interpolator = loadInterpolator(context, android.R.interpolator.fast_out_slow_in); } else { interpolator = loadInterpolator(context, android.R.anim.accelerate_decelerate_interpolator); } // create paths & rect now reuse & rewind later combinedUnselectedPath = new Path(); unselectedDotPath = new Path(); unselectedDotLeftPath = new Path(); unselectedDotRightPath = new Path(); rectF = new RectF(); addOnAttachStateChangeListener(new OnAttachStateChangeListener() { @Override public void onViewAttachedToWindow(View v) { attachedState = true; } @Override public void onViewDetachedFromWindow(View v) { attachedState = false; } }); }
From source file:com.nextgis.maplibui.formcontrol.Sign.java
protected void touchUp() { mPath.lineTo(mX, mY);/*from ww w. j av a 2s . c o m*/ postInvalidate(); // kill this so we don't double draw mPath = new Path(); mPaths.add(mPath); }
From source file:com.example.android.interpolator.InterpolatorFragment.java
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the fragment_animation layout View v = inflater.inflate(R.layout.interpolator_fragment, container, false); // Set up the 'animate' button, when it is clicked the view is animated with the options // selected: the Interpolator, duration and animation path Button button = (Button) v.findViewById(R.id.animateButton); button.setOnClickListener(new View.OnClickListener() { @Override/*from w w w . j av a 2 s .co m*/ public void onClick(View view) { // Interpolator selected in the spinner Interpolator interpolator = mInterpolators[mInterpolatorSpinner.getSelectedItemPosition()]; // Duration selected in SeekBar long duration = mDurationSeekbar.getProgress(); // Animation path is based on whether animating in or out Path path = mIsOut ? mPathIn : mPathOut; // Log animation details Log.i(TAG, String.format("Starting animation: [%d ms, %s, %s]", duration, (String) mInterpolatorSpinner.getSelectedItem(), ((mIsOut) ? "Out (growing)" : "In (shrinking)"))); // Start the animation with the selected options startAnimation(interpolator, duration, path); // Toggle direction of animation (path) mIsOut = !mIsOut; } }); // Get the label to display the selected duration mDurationLabel = (TextView) v.findViewById(R.id.durationLabel); // Initialize Interpolators programmatically by loading them from their XML definitions // provided by the framework. mInterpolators = new Interpolator[] { new AnimationUtils().loadInterpolator(getActivity(), android.R.interpolator.linear), new AnimationUtils().loadInterpolator(getActivity(), android.R.interpolator.fast_out_linear_in), new AnimationUtils().loadInterpolator(getActivity(), android.R.interpolator.fast_out_slow_in), new AnimationUtils().loadInterpolator(getActivity(), android.R.interpolator.linear_out_slow_in) }; // Load names of interpolators from a resource String[] interpolatorNames = getResources().getStringArray(R.array.interpolator_names); // Set up the Spinner with the names of interpolators mInterpolatorSpinner = (Spinner) v.findViewById(R.id.interpolatorSpinner); ArrayAdapter<String> spinnerAdapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_spinner_dropdown_item, interpolatorNames); mInterpolatorSpinner.setAdapter(spinnerAdapter); // Set up SeekBar that defines the duration of the animation mDurationSeekbar = (SeekBar) v.findViewById(R.id.durationSeek); // Register listener to update the text label when the SeekBar value is updated mDurationSeekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int i, boolean b) { mDurationLabel.setText(getResources().getString(R.string.animation_duration, i)); } @Override public void onStartTrackingTouch(SeekBar seekBar) { } @Override public void onStopTrackingTouch(SeekBar seekBar) { } }); // Set initial progress to trigger SeekBarChangeListener and update UI mDurationSeekbar.setProgress(INITIAL_DURATION_MS); // Get the view that will be animated mView = v.findViewById(R.id.square); // The following Path definitions are used by the ObjectAnimator to scale the view. // Path for 'in' animation: growing from 20% to 100% mPathIn = new Path(); mPathIn.moveTo(0.2f, 0.2f); mPathIn.lineTo(1f, 1f); // Path for 'out' animation: shrinking from 100% to 20% mPathOut = new Path(); mPathOut.moveTo(1f, 1f); mPathOut.lineTo(0.2f, 0.2f); return v; }
From source file:chrisrenke.drawerarrowdrawable.DrawerArrowDrawable.java
public DrawerArrowDrawable(Resources resources, boolean rounded) { this.rounded = rounded; float density = resources.getDisplayMetrics().density; float strokeWidthPixel = STROKE_WIDTH_DP * density; halfStrokeWidthPixel = strokeWidthPixel / 2; linePaint = new Paint(SUBPIXEL_TEXT_FLAG | ANTI_ALIAS_FLAG); linePaint.setStrokeCap(rounded ? ROUND : BUTT); linePaint.setColor(BLACK);//from w w w . ja v a 2s. co m linePaint.setStyle(STROKE); linePaint.setStrokeWidth(strokeWidthPixel); int dimen = (int) (DIMEN_DP * density); bounds = new Rect(0, 0, dimen, dimen); Path first, second; JoinedPath joinedA, joinedB; // Top first = new Path(); first.moveTo(5.042f, 20f); first.rCubicTo(8.125f, -16.317f, 39.753f, -27.851f, 55.49f, -2.765f); second = new Path(); second.moveTo(60.531f, 17.235f); second.rCubicTo(11.301f, 18.015f, -3.699f, 46.083f, -23.725f, 43.456f); scalePath(first, density); scalePath(second, density); joinedA = new JoinedPath(first, second); first = new Path(); first.moveTo(64.959f, 20f); first.rCubicTo(4.457f, 16.75f, 1.512f, 37.982f, -22.557f, 42.699f); second = new Path(); second.moveTo(42.402f, 62.699f); second.cubicTo(18.333f, 67.418f, 8.807f, 45.646f, 8.807f, 32.823f); scalePath(first, density); scalePath(second, density); joinedB = new JoinedPath(first, second); topLine = new BridgingLine(joinedA, joinedB); // Middle first = new Path(); first.moveTo(5.042f, 35f); first.cubicTo(5.042f, 20.333f, 18.625f, 6.791f, 35f, 6.791f); second = new Path(); second.moveTo(35f, 6.791f); second.rCubicTo(16.083f, 0f, 26.853f, 16.702f, 26.853f, 28.209f); scalePath(first, density); scalePath(second, density); joinedA = new JoinedPath(first, second); first = new Path(); first.moveTo(64.959f, 35f); first.rCubicTo(0f, 10.926f, -8.709f, 26.416f, -29.958f, 26.416f); second = new Path(); second.moveTo(35f, 61.416f); second.rCubicTo(-7.5f, 0f, -23.946f, -8.211f, -23.946f, -26.416f); scalePath(first, density); scalePath(second, density); joinedB = new JoinedPath(first, second); middleLine = new BridgingLine(joinedA, joinedB); // Bottom first = new Path(); first.moveTo(5.042f, 50f); first.cubicTo(2.5f, 43.312f, 0.013f, 26.546f, 9.475f, 17.346f); second = new Path(); second.moveTo(9.475f, 17.346f); second.rCubicTo(9.462f, -9.2f, 24.188f, -10.353f, 27.326f, -8.245f); scalePath(first, density); scalePath(second, density); joinedA = new JoinedPath(first, second); first = new Path(); first.moveTo(64.959f, 50f); first.rCubicTo(-7.021f, 10.08f, -20.584f, 19.699f, -37.361f, 12.74f); second = new Path(); second.moveTo(27.598f, 62.699f); second.rCubicTo(-15.723f, -6.521f, -18.8f, -23.543f, -18.8f, -25.642f); scalePath(first, density); scalePath(second, density); joinedB = new JoinedPath(first, second); bottomLine = new BridgingLine(joinedA, joinedB); }
From source file:com.xueyu.view.DrawerArrowDrawable.java
@SuppressLint("ResourceAsColor") public DrawerArrowDrawable(Resources resources, boolean rounded) { this.rounded = rounded; float density = resources.getDisplayMetrics().density; float strokeWidthPixel = STROKE_WIDTH_DP * density; halfStrokeWidthPixel = strokeWidthPixel / 2; linePaint = new Paint(SUBPIXEL_TEXT_FLAG | ANTI_ALIAS_FLAG); linePaint.setStrokeCap(rounded ? ROUND : BUTT); linePaint.setColor(R.color.white);/*w ww . j av a2s . c o m*/ linePaint.setStyle(STROKE); linePaint.setStrokeWidth(strokeWidthPixel); int dimen = (int) (DIMEN_DP * density); bounds = new Rect(0, 0, dimen, dimen); Path first, second; JoinedPath joinedA, joinedB; // Top first = new Path(); first.moveTo(5.042f, 20f); first.rCubicTo(8.125f, -16.317f, 39.753f, -27.851f, 55.49f, -2.765f); second = new Path(); second.moveTo(60.531f, 17.235f); second.rCubicTo(11.301f, 18.015f, -3.699f, 46.083f, -23.725f, 43.456f); scalePath(first, density); scalePath(second, density); joinedA = new JoinedPath(first, second); first = new Path(); first.moveTo(64.959f, 20f); first.rCubicTo(4.457f, 16.75f, 1.512f, 37.982f, -22.557f, 42.699f); second = new Path(); second.moveTo(42.402f, 62.699f); second.cubicTo(18.333f, 67.418f, 8.807f, 45.646f, 8.807f, 32.823f); scalePath(first, density); scalePath(second, density); joinedB = new JoinedPath(first, second); topLine = new BridgingLine(joinedA, joinedB); // Middle first = new Path(); first.moveTo(5.042f, 35f); first.cubicTo(5.042f, 20.333f, 18.625f, 6.791f, 35f, 6.791f); second = new Path(); second.moveTo(35f, 6.791f); second.rCubicTo(16.083f, 0f, 26.853f, 16.702f, 26.853f, 28.209f); scalePath(first, density); scalePath(second, density); joinedA = new JoinedPath(first, second); first = new Path(); first.moveTo(64.959f, 35f); first.rCubicTo(0f, 10.926f, -8.709f, 26.416f, -29.958f, 26.416f); second = new Path(); second.moveTo(35f, 61.416f); second.rCubicTo(-7.5f, 0f, -23.946f, -8.211f, -23.946f, -26.416f); scalePath(first, density); scalePath(second, density); joinedB = new JoinedPath(first, second); middleLine = new BridgingLine(joinedA, joinedB); // Bottom first = new Path(); first.moveTo(5.042f, 50f); first.cubicTo(2.5f, 43.312f, 0.013f, 26.546f, 9.475f, 17.346f); second = new Path(); second.moveTo(9.475f, 17.346f); second.rCubicTo(9.462f, -9.2f, 24.188f, -10.353f, 27.326f, -8.245f); scalePath(first, density); scalePath(second, density); joinedA = new JoinedPath(first, second); first = new Path(); first.moveTo(64.959f, 50f); first.rCubicTo(-7.021f, 10.08f, -20.584f, 19.699f, -37.361f, 12.74f); second = new Path(); second.moveTo(27.598f, 62.699f); second.rCubicTo(-15.723f, -6.521f, -18.8f, -23.543f, -18.8f, -25.642f); scalePath(first, density); scalePath(second, density); joinedB = new JoinedPath(first, second); bottomLine = new BridgingLine(joinedA, joinedB); }