ПрограммированиеФорум2D графика и изометрия

Построение меша текстурированной линии

#0
17:36, 22 окт 2010

Требуется построить меш для отрисовки текстурированной линии со скругленными переломами.
скругление ломанной | Построение меша текстурированной линии
имеются зеленые точки и ширина, нужно посчитать синие точки.
я конечно геометрию учил, и посчитал эти точки, но почемуто мне кажется что можно тут обойтись и без тригонометрии, лишь векторными операциями.
а вот с этим у меня до сих пор есть затруднения.
upd: на рисунке для красоты частный случай - излом 90градусов, естественно нужно общее решение

#1
18:23, 22 окт 2010

Зачем так много синих точек? Вы в чем гамите вообще?

#2
21:20, 22 окт 2010

AndryBlack
Выводи в месте сгиба сферу диаметра width, погруженную в каждый цилиндр на width/2
Сферу один раз строишь через gluQuadric и запоминаешь в glList, далее быстрый вывод списка, только масштабируешь до нужного радиуса
Кстати цилиндры тоже запоминаешь в отдельные glList-ы

#3
21:41, 22 окт 2010

Aslan
Ты серьезно? лучше не пиши ничего. Читай книжки

#4
22:47, 22 окт 2010

AndryBlack
Я тебе лучший вариант привел, чем что-то строить в динамике

#5
22:58, 22 окт 2010

Aslan, это не подходит, если требуется вывести неразрывную текстуру. Но в любом случае "округлость" изгиба будет конечной, так как там будет несколько вершин со своими uv-координатами. К тому же что делать с растяжками изображения? Это не критично?
AndryBlack, я правильно понял, всё уже реализовано, просто рассматривается другой вариант? Или пока просто рассматриваются все пути решения задачи?

И на всякий можно уточнить контекст задачи? Может быть есть другие подходы к решению? Насколько важна скорость?

#6
23:50, 22 окт 2010

Ну, все решаемо dot-ами.

float4 edge0( x0, y0, x1, y1 ), edge1( x0, y0, x2, y2 );

float4 e0 = normalize( edge0.zw - edge0.xy ), e1 = normalize( edge1.zw - edge1.xy );

float2 median = W / sqrt( (1-dot(e0,e1)) / 2 );

float2 corner = median + edge0.xy;
float2 outer0 = reflect( median, e0 ) + edge0.xy;
float2 outer1 = reflect( median, e1 ) + edge0.xy;

Думаю понятно, какие точки corner, outer0 и outer1 ?

#7
1:42, 23 окт 2010

Z
Спасибо, то что нужно. Только пара моментов.
1. Почему e1,e2 float4 а не float2
2. Откуда median float2 ?

#8
12:15, 25 окт 2010

AndryBlack
1. Опечатка
2. median назван немного коряво - ето тот вектор, что посередине между ребрами и образует два прямоугольнъх треугольника со стороной W. Откуда формула?
Косинус угла между ребрами ето dot(e0,e1) -> синус в 2 раза меньшего угла по формуле ето: sin(a/2) = sqrt[(1-cos(a)) / 2], а с другой сторонъ он равен W/median -> median = W/sqrt( (1-dot(e0,e1))/2)

#9
12:17, 25 окт 2010

Z
> 2. median назван немного коряво -
я к тому что он вроде как скаляром получается, W же скаляр
помоему его нужно домножить на (е1+е2)*0.5 чтоб вектором стал ?

#10
14:44, 25 окт 2010

AndryBlack
А, ну да, конечно - ето только длинна.

#11
14:57, 25 окт 2010

Z
функцию reflect не подскажешь как проще написать:

Vector2d reflect(const Vector2d& pos,const Vector2d& axis) {
   return axis*pos.dot(axis) + axis.normal()*(axis.normal().dot(axis));
}
#12
16:02, 25 окт 2010

Вот такие расчеты получились:
Z, спасибо еше раз

    painter.setPen(QPen(QColor(255,0,0)));

    drawControlPoint(painter,p0);
    drawControlPoint(painter,p1);
    drawControlPoint(painter,p2);

    drawLine(painter,p0,p1);
    drawLine(painter,p1,p2);

    Vector2d e1 = (p0-p1).unit();
    Vector2d e2 = (p2-p1).unit();

    float median_len = W / ::sqrt( ( 1.0f - e1.dot(e2) ) / 2.0f );
    Vector2d median_dir = (e1+e2).unit();
    Vector2d median = median_dir * median_len;
    float offset = median.dot(e1);

    Vector2d p0e = p1 + e1 * offset;
    Vector2d p2e = p1 + e2 * offset;


    Vector2d normal1 = e1.normal()*W;
    Vector2d normal2 = e2.normal()*W;

    
    painter.setPen(QPen(QColor(0,0,255)));

    drawControlPoint(painter,p0e);
    drawControlPoint(painter,p2e);
    
    painter.setPen(QPen(QColor(0,0,0)));

    drawLine(painter,p0+normal1,p0-normal1);
    drawLine(painter,p0-normal1,p0e-normal1);
    drawLine(painter,p0e+normal1,p0e-normal1);

    drawLine(painter,p2+normal2,p2-normal2);
    drawLine(painter,p2e+normal2,p2e-normal2);
    drawLine(painter,p2+normal2,p2e+normal2);

    painter.setPen(QPen(QColor(0,255,0)));
    drawLine(painter,p0+normal1,p0e+normal1);
    drawLine(painter,p2-normal2,p2e-normal2);
ПрограммированиеФорум2D графика и изометрия

Тема в архиве.