2012-03-25 3 views
2

저는 배열을 가지고 있습니다 : int [] [] lawn = new int [980] [1280];원 안에 모든 직교 좌표를 계산합니다.

잔디밭에 블레이드의 높이 값을 저장합니다.

내 시뮬레이션에는 잔디밭을 돌아 다니며 블레이드를 자르는 로봇이 있습니다.

내 로봇의 직경 (rDiameter)이 원의 형태입니다. 좌표계가 Double로 이루어졌고 잔디가 정수로 설정되었습니다.

나는 로봇이 잔디를자를 수있게 해주는 두 개의 "알고리즘"을 개발했지만 알고리즘의 정밀도가 충분히 높지 않아 성능이 좋지 않아 만족스럽지 않습니다.

제 질문은 이미 생각한 아이디어 외에 다른 방법이 있습니까?

더 나은 결과를 얻으려면 잔디밭을 바꿔야합니까?

충분히 명확하지 않은 경우 언제든지 물어보십시오. 여기

내 두 알고리즘 (k는 로봇의 약자), centerPosition 여기 내 로봇의 중심 (그래서 원의 중심)

approach with square 
    int bottomLeftCornerX = (int) (k.getCenterPosition().getX() - simulParams.getKDiameter()/2); 
    int bottomLeftCornerY = (int) (k.getCenterPosition().getY() - simulParams.getKDiameter()/2); 

    for (int i = bottomLeftCornerX; i < bottomLeftCornerX + simulParams.getKDiameter(); i++) { 
     for (int j = bottomLeftCornerY; j < bottomLeftCornerY + simulParams.getKDiameter(); j++) { 
      ((LawnArea) lawn.getBladeHeight()).cutBladeInArea(j, i); 
     } 
    } 

그리고 원 접근 방식의 하나를 반환하기위한 코드입니다 (기본적으로 그것은 위키 피 디아에있는 원색 형식입니다 ...) :

for (int r = 0; r < simulParams.getKDiameter()/2; r++) { 

     for (double t = 0; t < 2 * Math.PI; t = t + 0.1) { 
      Point2D p = circumference(k.getCenterPosition().getX(), k.getCenterPosition().getY(), t, r); 
      int intX = (int) Math.ceil(p.getX()); 
      int intY = (int) Math.ceil(p.getY()); 
       ((LawnArea) lawn.getBladeHeight()).cutBladeInArea(intY, intX); 
      } 
     } 
    } 
+0

중간 점 원 알고리즘을 사용하지 않고 좌표를 배열에 저장 한 다음 원을 한 줄씩 채우는 것은 어떻습니까? – harold

답변

0

: k.x는이 X 좌표, k.yk.r는 반경의 y 좌표이다. 두 개의 루프가

for(int y = (int)Math.max(0, Math.ceil(k.y - k.r)); y <= (int)Math.min(980, Math.floor(k.y + k.r)); y++) { 
    doulbe dx = Math.sqrt(k.r * k.r - Math.abs(y-k.y) * Math.abs(y-k.y)); 
    for(int x = Math.max(0, (int)Math.ceil(k.x - dx)); x <= (int)Math.min(1280, Math.floor(k.x + dx)); x++) { 
     cut(x,y); 
    } 
}

있습니다 : 항상 있었다면
첫 번째는 Y 좌표입니다 및 k.y - k.r에서 시작하여 원 필드에 completly 경우 k.y + k.r까지 간다 (나는 경우 몰랐다 그렇다면 구석에 닿을 수 없기 때문에 화면 상단에서 하단으로 이동합니다.
두 번째 것은 x 좌표입니다. 작고 큰 x는 공식 (k.x - x) ² + (k.y - y) ² = k.r²의 도움으로 계산됩니다.
그 점을 이용하면 서클에서만 포인트를 얻을 수 있습니다. double ~ int 변환으로 인해 조금 작습니다.

+0

답장을 보내 주셔서 감사합니다. 귀하의 코드를 시험해 보았지만 제대로 작동하지만, 제가 구석에 닿을 수 없다는 사실을 알지 못했습니다. – Seafire37

+0

두 배를 더 높은 값으로 반올림하는 지점에서 블레이드를 자르고 싶다면 공식을 사용하는 것이 가능합니까? – Seafire37

+0

정말 중요하지 않습니다. 나는 당신의 로봇이 그것을 떠날 수 있는지의 잔디밭에 항상 완전히 있는지 확실하지 않았습니다. – IchBinKeinBaum

1

첫 번째 방법 (경계 상자 기반)은 좋은 시작입니다. 그러나 경계 상자 안의 각 점이 원 안에 있는지 확인하는 조건을 추가하면됩니다. 같은

뭔가 :

for each (point p inside bounding-box) { 
    if (p inside circle centred at k) { 
     cutBlade(p); 
    } 
} 

당신은 경계 상자의 각 행 (또는 열)에 필요한 블레이드 세트가 절단 것을 알아 차리지하여이를 개선 할 수는 모두 이웃이다. 이 범위의 끝점을 계산하면 조건문이 필요하지 않습니다. 추천

뭔가 가독성 들어

for each (x inside bounding-box) { 
    calculate y_first; 
    calculate y_last; 
    for (y = y_first; y < y_last; y++) { 
     cutBlade(x,y); 
    } 
} 
+0

빠른 답장을 보내 주셔서 감사합니다. 다른 두 가지 아이디어가 있다면 알려 주시기 바랍니다. – Seafire37

관련 문제