2014-11-18 8 views
2
나는 아래의 이미지와 비슷한 그릴려고 처리를 사용하고

: 나는 this one 같은 일반 모양에 대한 bezierVertex를 사용하여 몇 가지 예를 본 적이다각형

enter image description here

을,하지만 난 것 내 모양의 꼭지점을 지정한 다음 모서리 반경을 지정할 수있는 간단한 그리기 메서드를 만드는 것을 좋아합니다. 뭔가 같은 myRoundedShape(x1, y1, x2, y2, x3, y3... xn, yn, cornerRadius) 어떤 아이디어?

+0

반올림되지 않은 다각형의 꼭지점의 (xn, yn) 좌표입니까? 그렇다면 둥근 폴리곤이 모든 (xn, yn) 점을 통과하지 않는다는 의미입니다. 맞습니까? – fang

+0

예, 그렇습니다. 둥근 다각형은 (xn, yn) 점을 통과하지 않습니다. – guardabrazo

+0

유용 할 수도있는이 링크 (http://stackoverflow.com/questions/24771828/algorithm-for-creating-rounded-corners-in-a-polygon)를 찾았습니다. – fang

답변

2

임의의 각도에 대해 둥근 모서리가 필요한 경우 베 지어 곡선이 가장 최악의 선택입니다. 수학은 어리 석없이 복잡하기 때문입니다. 대신, Catmull-Rom 커브를 사용하십시오. "에서까지 다음 커브가 발생합니다 : ..."로 정의 되었기 때문에 ... 대신으로 제어됩니다.

3 포인트 p1, p2 및 p3 사이의 모든 2 에지에 대해 p2의 왼쪽과 오른쪽, 가장자리 p1 - p2 및 p2 - p3을 따라 고정 된 위치에 새로운 포인트 p2l과 p2r을 만들 수 있습니다 거리 P2에서 "반경"

dx = p2.x-p1.x 
dy = p2.y-p1.y 
p2l = {x: p2.x - radius * dx, y: p2.y - radius * dy} 
p2l_guide = {x: p2.x - 3 * radius * dx, y: p2.y - 3 * radius * dy} 

dx = p3.x-p2.x 
dy = p3.y-p2.y 
p2r = {x: p2.x + radius * dx, y: p2.y + radius * dy} 
p2r_guide = {x: p2.x + 3 * radius * dx, y: p2.y + 3 * radius * dy} 

지금 P1 모양을 우리의 가장자리 - P2L 및 p2r - P3, 그리고 트릭에 P2L 및 p2r를 "연결"하는 것입니다 좋은 아크 - 틱 방법. {p2l_guide, P2L, p2r, p2r_guide 당신이 tubles의리스트가되기 위해 전처리 좌표 목록을해야합니다, 그래서 물론

beginShape(); 
curveVertex(p2l_guide.x,p2l_guide.y); 
curveVertex(p2l.x,p2l.y); 
curveVertex(p2r.x,p2r.y) 
curveVertex(p2r_guide.x,p2r_guide.y); 
endShape(); 

, 당신은 가장자리 쌍을 많이 다루고 : 그럼이 curveVertex 사용하자 } 대신 직선 p2r (n) - p2l (n + 1)로 연결 한 다음 p2l의 연결 곡선을 ..._ 안내 점에 의해 안내되는 p2r에 추가하십시오. 코드에서 : http://jsfiddle.net/drzp6L0g/3

이 솔루션은, 그래서 우리는 곡선 베 지어 필요하고, 우리가 같은 P2L 및 p2r 포인트를 결정해야합니다 줄 것이라는 점을 해결하기 위해, 가이드의 강도를 제어하는 ​​신비 변수 f으로 우리를 떠나지 않는다 그런 다음 some trigonometry을 적용하여 원호의 근사치 a를 적용하기 위해 제어 포인트가 필요한 것이 무엇인지 파악하십시오. 더 정확할뿐만 아니라 더 많은 작업을 할 수 있습니다.

이상적인 해결책은 물론 arcTo 명령을 사용하는 것입니다. 그러나 처리에는 실제로는없는 것이 이상적입니다. 그것은 arc() 명령을 가지고 있습니다. 셰이프 생성에서 분리되었습니다 (윤곽선이 필요하면 ... 괜찮습니다)!하지만 채워진 모양이 필요하다면, 행운이 없습니다.

+0

유망 해 보입니다. 나중에 더 자세히 살펴보고 답을 올바르게 표시하겠습니다. – guardabrazo

+0

"실제"3 차 베 지어 응답을 나중에 좀 더 많은 코드로 확장 할 수 있습니다. 수학은 관련되어 있지만 알려진 것이므로 대부분 "제대로 기능을 복사 할 수 있도록 올바른 값을 입력하십시오." –

+0

답변을 연장하려면 계속 진행하십시오.하지만 충분히 가깝다고 생각합니다. 지금은 파고 들어야 할 시간이 없기 때문에 더 똑똑한 해결책을 찾고있는 것입니다. 그러나 아직 존재하지 않는 것 같습니다. – guardabrazo

1

"radius"가있는 둥근 모서리를 원할 때 실제로는 원형 연결을 원하지 않을 때 이등변 삼각형 "tip"을 반올림합니다. 베 지어 커브를 사용하면 실제로 그렇게 쉽습니다.

우리가 삼각형 P2L 반올림 예정하고 있기 때문에 우리는 여전히 우리의 포인트가 P2L 및 p2r 오프셋 (offset)

- P2를 - p2r : 3 점, P1, P2와 P3 사이에 2 가장자리를 들어

, P2와 P2 - - 우리는 가장자리 (P1)를 따라 왼쪽과 P2의 오른쪽에 새로운 포인트가 P2L 및 p2r 만들 수 있습니다 P3를, P2에서 고정 된 거리 "반경"에서 :

dx = p2.x-p1.x 
dy = p2.y-p1.y 
p2l = {x: p2.x - radius * dx, y: p2.y - radius * dy} 

dx = p3.x-p2.x 
dy = p3.y-p2.y 
p2r = {x: p2.x + radius * dx, y: p2.y + radius * dy} 

(우리는 추가 가이드 포인트). 우리는 0, 다음 c1 == p2lc2 == p2r의 비율 거리를 선택하는 경우

start = p2l 
c1 = point somewhere on line p2l--p2, ratio distance `t` from p2l and `1-t` from p2 
c2 = point somewhere on line p2r--p2, using same ratio distance 
end = p2r 

, 우리는 직선을 얻을 : 우리는 지금과 같이 라운딩 작업을 정의 할 수 있습니다. 비율 거리 1을 선택한 다음 c1 == c2 == p2을 선택하면 가장 뾰족한 곡선을 얻을 수 있습니다. 보기 흉하지 않은 곡선의 경우, 0.5 또는 0.75의 값은 트릭을 잘합니다.

float[] roundIsosceles(Point p1, Point p2, Point p3, float t) { 
    float mt = 1-t, 
     c1x = (mt*p1.x + t*p2.x), 
     c1y = (mt*p1.y + t*p2.y), 
     c2x = (mt*p3.x + t*p2.x), 
     c2y = (mt*p3.y + t*p2.y); 
    return new float[]{ c1x, c1y, c2x, c2y }; 
} 

을 그리고 지금 우리는 점의 closed 목록을 기반으로 적절한 모양을 만들 수 있습니다 : 그래서 처음의 그 C1/C2 추출 기능을 정의 할 수

beginShape(); 
Point p1,p2,p3; 
for(int i=0, last=closed.size(); i<last; i+=3) { 
    p1 = closed.get(i); 
    p2 = closed.get(i+1); 
    p3 = closed.get(i+2); 

    // rounded isosceles triangle connector values: 
    float[] c = roundIsosceles(p1, p2, p3, 0.75); 

    // tell Processing that we have points to add to our shape: 
    vertex(p1.x,p1.y); 
    bezierVertex(c[0], c[1], c[2], c[3], p3.x, p3.y); 
} 
endShape(CLOSE); 

그리고 수행합니다. 그 결과는 무엇입니까? 실행 코드, 이것과 : http://jsfiddle.net/drzp6L0g/13 및 사진 등이 :

enter image description here

및 비율 0, 0.25, 0.5, 0.75 및 1 사이의 차이의 단순한 논증 :

enter image description here

+0

이것은 Catmull을 사용하는 매우 영리한 방법입니다 -Rom 커브를 사용하여 주어진 "둘러싸이지 않은"다각형 위에 반올림 효과를 얻습니다. 그러나 둥근 모서리는 지정된 반지름을 가진 원호가 아닙니다. – fang

+0

이들은 Catmull-Rom 곡선이 아닌 진정한 베 지어 곡선입니다 (둘 다 Hermite 곡선이지만 표현과 추상화 방법이 다릅니다).그리고 여러분 말이 맞습니다. 이것은 주어진 반지름을 기반으로하는 진정한 원형 반올림이 아니라 정중하게 둥근 모서리를 만듭니다. 나는이 대답을 세 번째로 나중에 재 작업 할 수도있다. =) –