Графика - Как я могу узнать, видна ли линия на экране с учетом ее ширины - PullRequest
4 голосов
/ 08 апреля 2011

Я делаю некоторую базовую графику, и мне интересно, как я узнаю, будет ли линия отображать некоторые ее части на экране.

Давайте возьмем линию, идущую от х-5, у3 к х2, у-7.Если его ширина составляет 1 пиксель, на экране ничего не отображается.Если его ширина составляет 15 пикселей, некоторые его части будут отображаться.

Как я могу это проверить?

1 Ответ

4 голосов
/ 11 апреля 2011

Если у вас есть только строки, вы можете работать с функцией ниже. В противном случае я бы порекомендовал пройти всю длину вашей линии и создать на определенном расстоянии квадрат ширины линии и проверить, находится ли он внутри вашего вида. Пример: если у вас есть строка от x0y0 до x7y0. Вы бы пошли к x1y0, чтобы создать квадрат размера линии рисования (в этом примере 15) и посмотреть, не перекрывает ли это ваш экран. Далее перейдите к x2y0 и так далее. Преимущество в том, что он будет работать даже с кривыми Безье (немного вики-информации о том, как будет работать Безье, будет достаточно).

// РЕДАКТИРОВАТЬ: (сделал небольшую функцию проверки Безье, должен работать, но не проверял) И я не думаю, что более эффективна проверка каждой строки перед рисованием:

- (void)bezierWithStart:(CGPoint)start cp1:(CGPoint)cp1 cp2:(CGPoint)cp2 end:(CGPoint)end withWidth:(float)wid {
    for (float i = 0.0; i<=1.0; i+=0.05) { // how many steps
        CGPoint chk1 = CGPointMake(start.x+((cp1.x-start.x)*i), start.y+((cp1.y-start.y)*i));
        CGPoint chk2 = CGPointMake(cp1.x+((cp2.x-cp1.x)*i), cp1.y+((cp2.y-cp1.y)*i));
        CGPoint chk3 = CGPointMake(cp2.x+((end.x-cp2.x)*i), cp2.y+((end.y-cp2.y)*i));

        CGPoint chk4 = CGPointMake(chk1.x+((chk2.x-chk1.x)*i), chk1.y+((chk2.y-chk1.y)*i));
        CGPoint chk5 = CGPointMake(chk2.x+((chk3.x-chk2.x)*i), chk2.y+((chk3.y-chk2.y)*i));

        CGPoint cPoint = CGPointMake(chk4.x+((chk5.x-chk4.x)*i), chk4.y+((chk5.y-chk4.y)*i));

        CGRect drawLine = CGRectMake(cPoint.x-(wid/2), cPoint.y-(wid/2), wid, wid);

        // check if rect is in view
    }
}

// РЕДАКТИРОВАТЬ конец

Но теперь давайте перейдем к простой функции строки:

- (void)testLine:(CGPoint)fp toSecond:(CGPoint)sp withWidth:(float)wid {
    float xratio = sp.x - fp.x;
    float yratio = sp.y - fp.y;
    double a = sqrt(((wid*wid)*(xratio*xratio))/((yratio*yratio)+(xratio*xratio)));
    a/=2; // because line width goes in both direction
    double b = (yratio/xratio)*a;
    if ((xratio<0.0 && yratio<0.0) || (xratio>0.0 && yratio>0.0))b*=-1;
    CGPoint diffFrom1 = CGPointMake(fp.x+a, fp.y+b);
    CGPoint diffTo1 = CGPointMake(sp.x+a, sp.y+b);
    a*=-1;
    b*=-1;
    CGPoint diffFrom2 = CGPointMake(fp.x+a, fp.y+b);
    CGPoint diffTo2 = CGPointMake(sp.x+a, sp.y+b);
}

вы получите 4 очка. 2 линии, одна выше и одна ниже исходной линии, в два раза меньше ширины вашего рисования. Вычисление позади, чтобы получить направление рисования и для этого разницу с исходной линией. Но для тех, кто хочет в нее попасть, вот мой предварительный расчет:

enter image description here

...