W ramach ładnych rzeczy - dziś była ładna pogoda w Juracie :-)
I w piekarni był on.....
Próbowałem też w kodzie popełnić dziś "ładne" paskudztwo ;-)
Rozwiązanie zadania "czy 2 odcinki się przecinają"... to jest proste... ale upierdliwe, więc żeby nie robić wyliczania case'ów, że o dx=0 dla pierwszego i tak dalej...
To poszedłem w coś takiego:
public double[] intersection(double[] startA, double[] endA, double[] startB, double[] endB) {
fixDirection(startA, endA, 0);
fixDirection(startB, endB, 0);
if (startA[0]-endA[0]==0 && startB[0]-endB[0]==0) {
fixDirection(startA, endA, 1);
fixDirection(startB, endB, 1);
}
var axisStart = new double[]{(startA[0]+startB[0])/2,(startA[1]+startB[1])/2};
var axisEnd = new double[]{(endA[0]+endB[0])/2,(endA[1]+endB[1])/2};
var axisMiddle = new double[]{(axisStart[0]+axisEnd[0])/2,(axisStart[1]+axisEnd[1])/2};
translate(startA, axisMiddle, -1);
translate(endA, axisMiddle, -1);
translate(startB, axisMiddle, -1);
translate(endB, axisMiddle, -1);
translate(axisStart, axisMiddle, -1);
translate(axisEnd, axisMiddle, -1);
var base = toPolar(axisEnd);
var polarStartA=toPolar(startA);
var polarEndA=toPolar(endA);
var polarStartB=toPolar(startB);
var polarEndB=toPolar(endB);
rotate(polarStartA, base, -1);
rotate(polarEndA, base, -1);
rotate(polarStartB, base, -1);
rotate(polarEndB, base, -1);
var a = fromPolar(polarStartA);
var b = fromPolar(polarEndA);
var c = fromPolar(polarStartB);
var d = fromPolar(polarEndB);
var solution = solution(a,b,c,d);
solution=toPolar(solution);
rotate(solution,base,1);
solution=fromPolar(solution);
translate(solution,axisMiddle,1);
return solution;
}
private double[] solution(double[] a, double[] b, double[] c, double[] d) {
var _ab1 = coeffs(a,b);
var _ab2 = coeffs(c,d);
var y = (_ab1[0]*_ab2[1]-_ab2[0]*_ab1[1])/(_ab1[0]-_ab2[0]);
var x = (y-_ab1[1])/_ab1[0];
return new double[]{x,y};
}
private double[] coeffs(double[] a, double[] b) {
var dx = b[0]-a[0];
var dy = b[1]-a[1];
// dx is almost guarantee not to be 0 ;-)
var _a = dy/dx;
var _b = a[1]-_a*a[0];
return new double[]{_a,_b};
}
private double[] fromPolar(double[] polar) {
return new double[]{Math.cos(polar[1])*polar[0], Math.sin(polar[1])*polar[0]};
}
private void rotate(double[] polarEndB, double[] base, int dir) {
polarEndB[1]+=base[1]*dir;
}
private double[] toPolar(double[] rect) {
var dx = rect[0];
var dy = rect[1];
var r = Math.sqrt(dx * dx + dy * dy);
var alpha = Math.atan2(dy,dx);
return new double[]{r, alpha};
}
private void translate(double[] startA, double[] axisMiddle, int dir) {
for (var i=0; i<2; i++) {
startA[i]+= axisMiddle[i]* dir;
}
}
private void fixDirection(double[] startA, double[] endA, int dir) {
if (startA[dir]>endA[dir]) {
var tmp = new double[2];
tmp[0]=startA[0];
tmp[1]=startA[1];
startA[0]=endA[0];
startA[1]=endA[1];
endA[0]=tmp[0];
endA[1]=tmp[1];
}
}
To może nie jest ładne, ale szalone ;-)
Więc żeby nie obsługiwać problemu gdy mi się równanie prostej y=a*x+b wykłada bo a by było równe nieskończoności to ja przekręcam układ współrzędnych tak by żaden z odcinków nie robił mi problemów, liczę w tym nowym układzie współrzędnych punkt przecięcia - jeśli jakiś jest, po czym wracam do oryginalnego układu współrzędnych ;p
To wszystko przez to, że ja akurat w programowaniu z wszystkim co jest w 2D mam problemy. Moja wyobraźnia niedomaga w tym obszarze i akurat mogę nie być w stanie sobie "wyliczyć" wszystkich przypadków (ale wyliczyć jako wyenumerować czyli powiedzieć przypadek 1, przypadek 2 i tak dalej)..
To może ładne nie jest, ale ładnie pokręcone ;-)
Ładne było tez dziś niebo.
Podobne postybeta
Plus dla Scala, minus dla Groovy ;-)
Jak szybciej znaleźć mniejszą i większą wartość? [opisowy tytuł, który niewiele mówi ;-)]
Maszyna stanów kontra labirynt ;-)
.asm - to było fajne rozszerzenie plików z programami ;-)
Trick w Java'ie ;-) czyli double brace initialization
Brak komentarzy:
Prześlij komentarz