Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.222.205.5] |
|
Сообщ.
#1
,
|
|
|
Здраствуйте.Помогите решить вторую половину задачи.
Первая половина представлена в файле.Её суть: дан отрезок и функция.Разделить отрезок на N равных частей и таблицу результатов занести в файл. А вот со второй задачей я вряд ли справлюсь.Её суть: между точками x[i] и x[i+1] построить кубический сплайн!!! Прикреплённый файлTAB.RAR (0.49 Кбайт, скачиваний: 150) |
Сообщ.
#3
,
|
|
|
Да был я там.Скачал delphi исходник.Да так и ничего и не понял.
|
Сообщ.
#4
,
|
|
|
Хорошо, А тебе именно для интерполяции или чего-то другого?
Добавлено И, вообще, какие параметры даны, а что надо вычислить. Приведи полностью задание. |
Сообщ.
#5
,
|
|
|
Вобщем, если ты читал статью, которую ты привёл, то всё тоже самое, только за исключением следующего:
между точками x[i] и x[i+1], которые у меня выводятся в файл в моей программе построить кубический сплайн (нарисовать его).Тоесть, если точке N=4, то будет три кубических сплайна (естественно коэффициенты у них будут разные в зависимости точек x): первый сплайн между a=x[1] и x[2]; второй - между x[2] и x[3]; третий - между x[3] и x[4]=b. |
Сообщ.
#6
,
|
|
|
Ну что - теперь ясно?
|
Сообщ.
#7
,
|
|
|
Falex, мне то ясно: надо или самому думать, или искать в интернете.
Мне это не надо, поэтому не ищу. |
Сообщ.
#8
,
|
|
|
А как тогда построить несколько графиков функции на разных отрезках.Например:
x*x на [5,10] x*x*x на [10,15] exp(x) на [15,20] |
Сообщ.
#9
,
|
|
|
Сообщ.
#10
,
|
|
|
Чтобы это всё в цикле было.
Если я например найду эти полиномы для всех точек, то мне надо их как-то нарисовать (причёт строго между точками)!! |
Сообщ.
#11
,
|
|
|
Falex, похоже, ты просто хочешь, чтобы за тебя написали программу.
Если так, то я могу направить топик прямо в раздел "Работа". Там за деньги тебе с радостью помогут. Цитата Falex @ мне надо их как-то нарисовать (причёт строго между точками)! Пример там есть! Только бери, да подставляй свои функции. |
Сообщ.
#12
,
|
|
|
Интересно как я деньги буду платить?
P.S>Но я не собираюсь. |
Сообщ.
#13
,
|
|
|
Вот это тебе, возможно, поможет.
{$N+} Unit Curves; Interface Uses Graph; Procedure Curve (x1, y1, x2, y2, x3, y3: Integer; Segments: Word); Procedure CubicBezierCurve (x1, y1, x2, y2, x3, y3, x4, y4: Integer; Segments: Word); Procedure BSpline (NumPoints: Word; Points: array of pointtype; Segments: Word); Procedure Catmull_Rom_Spline (NumPoints: Word; Points: Array Of pointtype; Segments: Word); {----------------------------------------------------------------------------} Implementation Procedure Curve (x1, y1, x2, y2, x3, y3: Integer; Segments: Word); { Draw a curve from (x1,y1) through (x2,y2) to (x3,y3) divided in "Segments" segments } Var lsteps, ex, ey, fx, fy: LongInt; t1, t2: Integer; Begin x2:=(x2 SHL 1)-((x1+x3) SHR 1); y2:=(y2 SHL 1)-((y1+y3) SHR 1); lsteps:=Segments; If (lsteps<2) then lsteps:=2; If (lsteps>128) then lsteps:=128; { Clamp value to avoid overcalculation } ex:=(LongInt (x2-x1) SHL 17) DIV lsteps; ey:=(LongInt (y2-y1) SHL 17) DIV lsteps; fx:=(LongInt (x3-(2*x2)+x1) SHL 16) DIV (lsteps*lsteps); fy:=(LongInt (y3-(2*y2)+y1) SHL 16) DIV (lsteps*lsteps); Dec (lsteps); While lsteps>0 Do Begin t1:=x3; t2:=y3; x3:=(((fx*lsteps+ex)*lsteps) SHR 16)+x1; y3:=(((fy*lsteps+ey)*lsteps) SHR 16)+y1; Line ( t1,t2,x3,y3 ); Dec (lsteps); End; Line ( x3,y3,x1,y1 ); End; Procedure CubicBezierCurve (x1, y1, x2, y2, x3, y3, x4, y4: Integer; Segments: Word); { Draw a cubic bezier-curve using the basis functions directly } Var tx1, tx2, tx3, ty1, ty2, ty3, mu, mu2, mu3, mudelta: Real; xstart, ystart, xend, yend, n: Integer; Begin If (Segments<1) then Exit; If Segments>128 then Segments:=128; { Clamp value to avoid overcalculation } mudelta:=1/Segments; mu:=0; tx1:=-x1+3*x2-3*x3+x4; ty1:=-y1+3*y2-3*y3+y4; tx2:=3*x1-6*x2+3*x3; ty2:=3*y1-6*y2+3*y3; tx3:=-3*x1+3*x2; ty3:=-3*y1+3*y2; xstart:=x1; ystart:=y1; mu:=mu+mudelta; For n:=1 to Segments Do Begin mu2:=mu*mu; mu3:=mu2*mu; xend:=Round (mu3*tx1+mu2*tx2+mu*tx3+x1); yend:=Round (mu3*ty1+mu2*ty2+mu*ty3+y1); Line ( xstart, ystart, xend, yend ); mu:=mu+mudelta; xstart:=xend; ystart:=yend; End; End; Procedure Catmull_Rom_Spline (NumPoints: Word; Points: Array Of pointtype; Segments: Word); { Draw a spline approximating a curve defined by the array of points. } { In contrast to the BSpline this curve will pass through the points } { defining is except the first and the last point. The curve will only } { pass through the first and the last point if these points are given } { twice after eachother, like this: } { Array of points: } { } { First point defined twice Last point defined twice } { |-----| |----------| } { (0,0),(0,0),(100,100),....,(150,100),(200,200),(200,200) } { the curve defined by these points will pass through all the points. } Function Calculate (mu: Real; p0, p1, p2, p3: Integer): Integer; Var mu2, mu3: Real; Begin mu2:=mu*mu; mu3:=mu2*mu; Calculate:=Round ((1/2)*(mu3*(-p0+3*p1-3*p2+p3)+ mu2*(2*p0-5*p1+4*p2-p3)+ mu *(-p0+p2)+(2*p1))); End; Var mu, mudelta: Real; x1, y1, x2, y2, n, h: Integer; Begin If (NumPoints<4) Or (NumPoints>16383) then Exit; mudelta:=1/Segments; For n:=3 to NumPoints-1 Do Begin mu:=0; x1:=Calculate (mu,Points[n-3].x,Points[n-2].x,Points[n-1].x,Points[n].x); y1:=Calculate (mu,Points[n-3].y,Points[n-2].y,Points[n-1].y,Points[n].y); mu:=mu+mudelta; For h:=1 to Segments Do Begin x2:=Calculate (mu,Points[n-3].x,Points[n-2].x,Points[n-1].x,Points[n].x); y2:=Calculate (mu,Points[n-3].y,Points[n-2].y,Points[n-1].y,Points[n].y); Line ( x1, y1, x2, y2 ); mu:=mu+mudelta; x1:=x2; y1:=y2; End; End; End; Procedure BSpline (NumPoints: Word; Points: Array of Pointtype; Segments: Word); type Rmas=array[0..10] of real; Var i,oldy,oldx,x,y,j:integer; part,t,xx,yy,xmin,xmax,sum:real; dx,dy,wx,wy,px,py,xp,yp,temp,path,zc,u:Rmas; Function f(g:real):real; begin f:=g*g*g-g; end; Begin if NumPoints>10 then exit; oldx:=999; x:=Points[0].x; y:=Points[0].y; zc[0]:=0.0; for i:=1 to NumPoints do begin xx:=Points[i-1].x-Points[i].x; yy:=Points[i-1].y-Points[i].y; t:=sqrt(xx*xx+yy*yy); zc[i]:=zc[i-1]+t; {establish a proportional linear progression} end; {Calculate x & y matrix stuff} for i:=1 to NumPoints-1 do begin dx[i]:=2*(zc[i+1]-zc[i-1]); dy[i]:=2*(zc[i+1]-zc[i-1]); end; for i:=0 to NumPoints-1 do begin u[i]:=zc[i+1]-zc[i]; end; for i:=1 to NumPoints-1 do begin wy[i]:=6*((Points[i+1].y-Points[i].y)/u[i]-(Points[i].y-Points[i-1].y)/u[i-1]); wx[i]:=6*((Points[i+1].x-Points[i].x)/u[i]-(Points[i].x-Points[i-1].x)/u[i-1]); end; py[0]:=0.0; px[0]:=0.0; px[1]:=0; py[1]:=0; py[NumPoints]:=0.0; px[NumPoints]:=0.0; for i:=1 to NumPoints-2 do begin wy[i+1]:=wy[i+1]-wy[i]*u[i]/dy[i]; dy[i+1]:=dy[i+1]-u[i]*u[i]/dy[i]; wx[i+1]:=wx[i+1]-wx[i]*u[i]/dx[i]; dx[i+1]:=dx[i+1]-u[i]*u[i]/dx[i]; end; for i:=NumPoints-1 downto 1 do begin py[i]:=(wy[i]-u[i]*py[i+1])/dy[i]; px[i]:=(wx[i]-u[i]*px[i+1])/dx[i]; end; { Draw spline } for i:=0 to NumPoints-1 do begin for j:=0 to 30 do begin part:=zc[i]-(((zc[i]-zc[i+1])/30)*j); t:=(part-zc[i])/u[i]; part:=t*Points[i+1].y+(1-t)*Points[i].y+u[i]*u[i]*(f(t)*py[i+1]+f(1-t)*py[i])/6.0; y:=round(part); part:=zc[i]-(((zc[i]-zc[i+1])/30)*j); t:=(part-zc[i])/u[i]; part:=t*Points[i+1].x+(1-t)*Points[i].x+u[i]*u[i]*(f(t)*px[i+1]+f(1-t)*px[i])/6.0; x:=round(part); if oldx<>999 then line(oldx,oldy,x,y); oldx:=x; oldy:=y; end; end; end; END. |
Сообщ.
#14
,
|
|
|
Интересно - что это такое?И как этим unitom пользоваться?
Лучше на моём примере бы объяснил! Добавлено Пример для этого unita есть? А то вот та кне получается: program spline; uses crt,graph,splineUnit; begin grDriver:=Detect; InitGraph(grDriver,gMode,'c:\pascal'); Curve(0,0,5,5,8,8,3); end. |
Сообщ.
#15
,
|
|
|
program CurveTst; uses Crt, Graph, v256,{} (* модуль поддержки 256-цветных режимов графики *) Curves; Const segments = 30; var x1, y1, x2, y2, x3, y3, gd, gm : integer; begin { gd := Detect; InitGraph (gd, gm, '..\bgi');{} SetVMode(v640x480);{} { SetBkColor(LightGray);{} repeat ClearDevice; x1 := random (GetMaxX); y1 := random (GetMaxY); x2 := random (GetMaxX); y2 := random (GetMaxY); x3 := random (GetMaxX); y3 := random (GetMaxY); SetColor (1 + Random (GetMaxColor)); Curve (x1, y1, x2, y2, x3, y3, segments); delay (600) until keypressed; CloseGraph; end. Прикреплённый файлV256.zip (4.08 Кбайт, скачиваний: 182) |
Сообщ.
#16
,
|
|
|
А если вместо x и y взять конкретное значение?
Вот я взял и ничего не ваышло x1 := 5; y1 := 25; x2 := round(6.25); y2 := round(39.0625); x3 := round(7.5); y3 := round(56.25); И для моей программы ведь надо брать процедуру BSpline или Catmull_Rom_Spline? (и чем они отличаются). Вот именно для той процедуры , которая мне нужна, приведи пожалуйста пример. |
Сообщ.
#17
,
|
|
|
Xn,Yn - то координаты на экране, то есть пиксели (целые числа)!
Добавлено Цитата Eugie Способов интерполяции много, наиболее практичный - с помощью сплайнов. Cплайн - это интерполирующая кривая с заданной степенью гладкости, проходящая через набор точек (узлов). Реализуют сплайны с помощью многочленов, т.е. участки кривой между соседними узлами представляют собой многочлены; при этом их коэффициенты определяются из условия равенства значений соседних многочленов и их производных (порядка до нужной степени гладкости) в узлах плюс несколько доп.условий на производные в крайних точках. Например, для кубических сплайнов имеем: пусть (x[1],y[1]),...,(x[N],y[N]) - набор узлов; F[n](x):=a[n]*x^3+b[n]*x^2+c[n]*x+d[n], n:=1,...,N-1 - набор кубических многочленов. Тогда система уравнений F [n](x[k]) := y[k], n:=(1..N-1), k:=(n,n+1), F' [n](x[n+1]) := F' [n+1](x[n+1]), n:=(1..N-2), F''[n](x[n+1]) := F''[n+1](x[n+1]), n:=(1..N-2), F''[1](x[1]) := 0, F''[N](x[N]) := 0 (эти два условия произвольные) однозначно определяет коэффициенты многочленов для построения кубического сплайна. Действительно, имеем 4(N-1) переменных a[n],b[n],c[n],d[n] для n := (1..N-1) и столько же уравнений. Описанная схема не самая эффективная, в литературе можно найти алгоритмы построения сплайнов, требующие решения всего N+1 линейных ур-й, причем прогонкой. Рекомендую помотреть, например, справочник по математике Бронштейна и Семендяева. В Дельфи для построения используются методы PolyBezier и PolyBezierTo класса Canvas. Цитата Строит кривую Безье (кубический сплайн), используя массив координат точек Points Добавлено Почитай также и это: Линии Безье Использование кривых Безье |
Сообщ.
#18
,
|
|
|
Цитата Xn,Yn - то координаты на экране, то есть пиксели (целые числа) Значит кокретные числе нельзя брать?(и какие например можно?) Для моей программы надо брать процедуру BSpline или Catmull_Rom_Spline? |
Сообщ.
#19
,
|
|
|
Цитата Falex @ Значит кокретные числе нельзя брать?(и какие например можно?) целые числа - это ординарные типы Byte,Word,Integer,Longint. Что будешь вставлять вместо параметров в функцию: константы, переменные или результаты функций - компилятору до лампочки. Я ясно выражаюсь? Цитата Falex @ Для моей программы надо брать процедуру BSpline или Catmull_Rom_Spline? По-моему, всё-таки процедура CubicBezierCurve. Тебе ведь нужен кубический сплайн. Falex, ты читал то, что я тебе давал? Если проблема именно в отображении сплайна, то тебе надо задавать масштаб увеличения Scale вещественного типа: X1 := Random (Scale * 7.5); Scale должна быть не менее 10.0, но и не слишком большая, иначе кривая выйдет за пределы экрана. |
Сообщ.
#20
,
|
|
|
Попробовал вот так, но почему-то pascal из малоэкранного режима при компиляции переходит в полноэкранный,где ни
одна клавиша не работает, кроме Windows. Scale:=75; InitGraph (gd, gm, 'c:\pascal'); ClearDevice; x1 := random (8*Scale); y1 := random (10*Scale); x2 := random (10*Scale); y2 := random (12*Scale); x3 := random (12*Scale); y3 := random (14*Scale);; Curve (x1, y1, x2, y2, x3, y3, segments); CloseGraph; end. И какой всё таки пример для моей функции (P.S>исходники на Delphi смотрел,но это же не pascal - и сама задача стоит по иному) |
Сообщ.
#21
,
|
|
|
Цитата Falex @ Scale:=75; InitGraph (gd, gm, 'c:\pascal'); ClearDevice; {зачем это здесь нужно???} x1 := random (8*Scale); y1 := random (10*Scale); x2 := random (10*Scale); y2 := random (12*Scale); x3 := random (12*Scale); y3 := random (14*Scale);; Curve (x1, y1, x2, y2, x3, y3, segments); {А где задержка перед выходом из программы???} CloseGraph; end. Перед CloseGraph обязательно должна быть какая-то задержка, чтобы пользователь смог что-то увидеть перед закрытием программы. Вставь Readln; У тебя при запуске программы графический режим устанавливается, потом сразу же и закрывается. Вижу, что с Паскалем у тебя туго. |
Сообщ.
#22
,
|
|
|
И какой всё таки пример для моей функции!
|
Сообщ.
#23
,
|
|
|
Ну сам, в конце концов, можешь подумать? Почитать где-то. Или за тебя все должны искать и предлагать готовые решения?
|