আমি একটি অ্যালগরিদম তৈরি করেছি যা যে কোনও বাঁক অর্থাৎ পাথকে ন্যূনতম সংখ্যায় রূপান্তর করে যাতে আমি এটি একটি ফাইল বা ডাটাবেসে সংরক্ষণ করতে পারি।
পদ্ধতিটি সহজ: এটি তিনটি পয়েন্টকে সমান ধাপে সরায় এবং এই পয়েন্টগুলির আকারের রেখার মধ্যবর্তী কোণটি পরিমাপ করে। যদি কোণটি সহনশীলতার চেয়ে বড় হয় তবে এটি সেই বিন্দুতে একটি নতুন ঘনকীয় বক্ররেখা তৈরি করে। তারপরে এটি লাইনগুলি এগিয়ে নিয়ে যায় এবং আবার কোণটি পরিমাপ করে ...
যারা অ্যান্ড্রয়েড পাথ ক্লাস জানেন তাদের জন্য - নোট করুন যে ডিএসটিপথটি একটি কাস্টম শ্রেণি, যা পয়েন্টগুলি একটি অ্যারেতে রেকর্ড করে তাই আমি পয়েন্টগুলি পরে সংরক্ষণ করতে পারি, যখন এসসিআরপথ একটি অঞ্চল ইউনিয়নের ফলাফল এবং তাই আমার জন্য কোনও মূল পয়েন্ট নেই has বাঁচাতে.
সমস্যাটি হ'ল নীচের কোড দ্বারা উত্পাদিত এই চিত্রটিতে যেমন দেখতে পাবেন তেমন বৃত্তটি মসৃণ দেখাচ্ছে না, যেখানে উত্স পথটি একটি নিখুঁত বৃত্ত এবং আয়তক্ষেত্র নিয়ে গঠিত। আমি সহনশীলতার কোণ এবং পদক্ষেপগুলির দৈর্ঘ্য পরিবর্তন করার চেষ্টা করেছি, তবে কিছুই সাহায্য করে না। আমি ভাবছি যদি আপনি এই অ্যালগরিদম বা অন্য কোনও পদ্ধতির কোনও উন্নতি প্রস্তাব করতে পারেন।
সম্পাদনা: যারা এখন অ্যান্ড্রয়েড জাভা ব্যবহার করেন তাদের জন্য আমি পুরো কোডটি পোস্ট করেছি, যাতে তারা সহজেই চেষ্টা ও পরীক্ষা করতে পারে।
public class CurveSavePointsActivity extends Activity{
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new CurveView(this));
}
class CurveView extends View{
Path srcPath, dstPath;
Paint srcPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
Paint dstPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
public CurveView(Context context) {
super(context);
srcPaint.setColor(Color.BLACK);
srcPaint.setStyle(Style.STROKE);
srcPaint.setStrokeWidth(2);
srcPaint.setTextSize(20);
dstPaint.setColor(Color.BLUE);
dstPaint.setStyle(Style.STROKE);
dstPaint.setStrokeWidth(2);
dstPaint.setTextSize(20);
srcPath = new Path();
dstPath = new Path();
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
//make a circle path
srcPath.addCircle(w/4, h/2, w/6 - 30, Direction.CW);
//make a rectangle path
Path rectPath = new Path();
rectPath.addRect(new RectF(w/4, h/2 - w/16, w*0.5f, h/2 + w/16), Direction.CW);
//create a path union of circle and rectangle paths
RectF bounds = new RectF();
srcPath.computeBounds(bounds, true);
Region destReg = new Region();
Region clip = new Region();
clip.set(new Rect(0,0, w, h));
destReg.setPath(srcPath, clip);
Region srcReg = new Region();
srcReg.setPath(rectPath, clip);
Region resultReg = new Region();
resultReg.op(destReg, srcReg, Region.Op.UNION);
if(!resultReg.isEmpty()){
srcPath.reset();
srcPath.addPath(resultReg.getBoundaryPath());
}
//extract a new path from the region boundary path
extractOutlinePath();
//shift the resulting path bottom left, so they can be compared
Matrix matrix = new Matrix();
matrix.postTranslate(10, 30);
dstPath.transform(matrix);
}
@Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawColor(Color.WHITE);
canvas.drawPath(srcPath, srcPaint);
canvas.drawPath(dstPath, dstPaint);
canvas.drawText("Source path", 40, 50, srcPaint);
canvas.drawText("Destination path", 40, 100, dstPaint);
}
public void extractOutlinePath() {
PathMeasure pm = new PathMeasure(srcPath, false); //get access to curve points
float p0[] = {0f, 0f}; //current position of the new polygon
float p1[] = {0f, 0f}; //beginning of the first line
float p2[] = {0f, 0f}; //end of the first & the beginning of the second line
float p3[] = {0f, 0f}; //end of the second line
float pxStep = 5; //sampling step for extracting points
float pxPlace = 0; //current place on the curve for taking x,y coordinates
float angleT = 5; //angle of tolerance
double a1 = 0; //angle of the first line
double a2 = 0; //angle of the second line
pm.getPosTan(0, p0, null); //get the beginning x,y of the original curve into p0
dstPath.moveTo(p0[0], p0[1]); //start new path from the beginning of the curve
p1 = p0.clone(); //set start of the first line
pm.getPosTan(pxStep, p2, null); //set end of the first line & the beginning of the second
pxPlace = pxStep * 2;
pm.getPosTan(pxPlace, p3, null); //set end of the second line
while(pxPlace < pm.getLength()){
a1 = 180 - Math.toDegrees(Math.atan2(p1[1] - p2[1], p1[0] - p2[0])); //angle of the first line
a2 = 180 - Math.toDegrees(Math.atan2(p2[1] - p3[1], p2[0] - p3[0])); //angle of the second line
//check the angle between the lines
if (Math.abs(a1-a2) > angleT){
//draw a straight line to the first point if the current p0 is not already there
if(p0[0] != p1[0] && p0[1] != p1[1]) dstPath.quadTo((p0[0] + p1[0])/2, (p0[1] + p1[1])/2, p1[0], p1[1]);
dstPath.quadTo(p2[0] , p2[1], p3[0], p3[1]); //create a curve to the third point through the second
//shift the three points by two steps forward
p0 = p3.clone();
p1 = p3.clone();
pxPlace += pxStep;
pm.getPosTan(pxPlace, p2, null);
pxPlace += pxStep;
pm.getPosTan(pxPlace, p3, null);
if (pxPlace > pm.getLength()) break;
}else{
//shift three points by one step towards the end of the curve
p1 = p2.clone();
p2 = p3.clone();
pxPlace += pxStep;
pm.getPosTan(pxPlace, p3, null);
}
}
dstPath.close();
}
}
}
এখানে মূল এবং আমার অ্যালগরিদম যা উত্পাদন করে তার মধ্যে একটি তুলনা করা হয়েছে: