3 |
3 |
4 uses uLandTemplates, uLandOutline; |
4 uses uLandTemplates, uLandOutline; |
5 |
5 |
6 procedure GenTemplated(var Template: TEdgeTemplate); |
6 procedure GenTemplated(var Template: TEdgeTemplate); |
7 procedure DivideEdges(fillPointsCount: LongWord; var pa: TPixAr); |
7 procedure DivideEdges(fillPointsCount: LongWord; var pa: TPixAr); |
|
8 |
|
9 var minDistance, dabDiv: LongInt; // different details size |
8 |
10 |
9 implementation |
11 implementation |
10 uses uVariables, uConsts, uFloat, uLandUtils, uRandom, SDLh, math; |
12 uses uVariables, uConsts, uFloat, uLandUtils, uRandom, SDLh, math; |
11 |
13 |
12 |
14 |
95 BezierizeEdge(pa, _0_1); |
97 BezierizeEdge(pa, _0_1); |
96 end; |
98 end; |
97 |
99 |
98 procedure FindPoint(si: LongInt; fillPointsCount: LongWord; var newPoint: TPoint; var pa: TPixAr); |
100 procedure FindPoint(si: LongInt; fillPointsCount: LongWord; var newPoint: TPoint; var pa: TPixAr); |
99 const mapBorderMargin = 40; |
101 const mapBorderMargin = 40; |
100 minDistance = 32; // adjust/parametrize this for different details size |
|
101 var p1, p2, p4, fp, mp: TPoint; |
102 var p1, p2, p4, fp, mp: TPoint; |
102 i, t1, t2, iy, ix, aqpb: LongInt; |
103 i, t1, t2, iy, ix, aqpb: LongInt; |
103 a, b, p, q: LongInt; |
104 a, b, p, q: LongInt; |
104 dab, d, distL, distR: LongInt; |
105 dab, d, distL, distR: LongInt; |
105 begin |
106 begin |
125 mp.x:= (p1.x + p2.x) div 2; |
126 mp.x:= (p1.x + p2.x) div 2; |
126 mp.y:= (p1.y + p2.y) div 2; |
127 mp.y:= (p1.y + p2.y) div 2; |
127 |
128 |
128 // don't process too short segments or those which are too close to map borders |
129 // don't process too short segments or those which are too close to map borders |
129 if (p1.x = NTPX) |
130 if (p1.x = NTPX) |
130 or (dab < minDistance * 3) |
131 or (dab < minDistance * 3) |
131 or (mp.x < LongInt(leftX) + mapBorderMargin) |
132 or (mp.x < LongInt(leftX) + mapBorderMargin) |
132 or (mp.x > LongInt(rightX) - mapBorderMargin) |
133 or (mp.x > LongInt(rightX) - mapBorderMargin) |
133 or (mp.y < LongInt(topY) + mapBorderMargin) |
134 or (mp.y < LongInt(topY) + mapBorderMargin) |
134 or (mp.y > LongInt(LAND_HEIGHT) - mapBorderMargin) |
135 or (mp.y > LongInt(LAND_HEIGHT) - mapBorderMargin) |
135 then |
136 then |
146 d:= DistanceI(mp.x - leftX - mapBorderMargin, mp.y - iy).Round; |
147 d:= DistanceI(mp.x - leftX - mapBorderMargin, mp.y - iy).Round; |
147 t1:= a * (mp.x - mapBorderMargin) + b * (mp.y - iy); |
148 t1:= a * (mp.x - mapBorderMargin) + b * (mp.y - iy); |
148 if t1 > 0 then distL:= d else distR:= d; |
149 if t1 > 0 then distL:= d else distR:= d; |
149 |
150 |
150 // right border |
151 // right border |
151 iy:= (rightX - mapBorderMargin - mp.x) * b div a + mp.y; |
152 iy:= (LongInt(rightX) - mapBorderMargin - mp.x) * b div a + mp.y; |
152 d:= DistanceI(mp.x - rightX + mapBorderMargin, mp.y - iy).Round; |
153 d:= DistanceI(mp.x - rightX + mapBorderMargin, mp.y - iy).Round; |
153 if t1 > 0 then distR:= d else distL:= d; |
154 if t1 > 0 then distR:= d else distL:= d; |
|
155 end else |
|
156 begin |
|
157 distL:= LAND_WIDTH + LAND_HEIGHT; |
|
158 distR:= distL; |
154 end; |
159 end; |
155 |
160 |
156 if b <> 0 then |
161 if b <> 0 then |
157 begin |
162 begin |
158 // top border |
163 // top border |
189 aqpb:= a * q - p * b; |
194 aqpb:= a * q - p * b; |
190 |
195 |
191 if (aqpb <> 0) then |
196 if (aqpb <> 0) then |
192 begin |
197 begin |
193 // (ix; iy) is intersection point |
198 // (ix; iy) is intersection point |
194 iy:= ((Int64(pa.ar[i].x - mp.x) * b + Int64(mp.y) * a) * q - Int64(pa.ar[i].y) * p * b) div aqpb; |
199 iy:= (((Int64(pa.ar[i].x) - mp.x) * b + Int64(mp.y) * a) * q - Int64(pa.ar[i].y) * p * b) div aqpb; |
195 if abs(b) > abs(q) then |
200 if abs(b) > abs(q) then |
196 ix:= (iy - mp.y) * a div b + mp.x |
201 ix:= (iy - mp.y) * a div b + mp.x |
197 else |
202 else |
198 ix:= (iy - pa.ar[i].y) * p div q + pa.ar[i].x; |
203 ix:= (iy - pa.ar[i].y) * p div q + pa.ar[i].x; |
199 |
204 |
220 aqpb:= a * q - p * b; |
225 aqpb:= a * q - p * b; |
221 |
226 |
222 if (aqpb <> 0) then |
227 if (aqpb <> 0) then |
223 begin |
228 begin |
224 // (ix; iy) is intersection point |
229 // (ix; iy) is intersection point |
225 iy:= ((Int64(p1.x - mp.x) * b + Int64(mp.y) * a) * q - Int64(p1.y) * p * b) div aqpb; |
230 iy:= (((Int64(p1.x) - mp.x) * b + Int64(mp.y) * a) * q - Int64(p1.y) * p * b) div aqpb; |
226 if abs(b) > abs(q) then |
231 if abs(b) > abs(q) then |
227 ix:= (iy - mp.y) * a div b + mp.x |
232 ix:= (iy - mp.y) * a div b + mp.x |
228 else |
233 else |
229 ix:= (iy - p1.y) * p div q + p1.x; |
234 ix:= (iy - p1.y) * p div q + p1.x; |
230 |
235 |
239 aqpb:= a * q - p * b; |
244 aqpb:= a * q - p * b; |
240 |
245 |
241 if (aqpb <> 0) then |
246 if (aqpb <> 0) then |
242 begin |
247 begin |
243 // (ix; iy) is intersection point |
248 // (ix; iy) is intersection point |
244 iy:= ((Int64(p2.x - mp.x) * b + Int64(mp.y) * a) * q - Int64(p2.y) * p * b) div aqpb; |
249 iy:= (((Int64(p2.x) - mp.x) * b + Int64(mp.y) * a) * q - Int64(p2.y) * p * b) div aqpb; |
245 if abs(b) > abs(q) then |
250 if abs(b) > abs(q) then |
246 ix:= (iy - mp.y) * a div b + mp.x |
251 ix:= (iy - mp.y) * a div b + mp.x |
247 else |
252 else |
248 ix:= (iy - p2.y) * p div q + p2.x; |
253 ix:= (iy - p2.y) * p div q + p2.x; |
249 |
254 |
254 end; |
259 end; |
255 end; |
260 end; |
256 |
261 |
257 // don't move new point for more than length of initial segment |
262 // don't move new point for more than length of initial segment |
258 // adjust/parametrize for more flat surfaces (try values 3/4, 1/2 of dab, or even 1/4) |
263 // adjust/parametrize for more flat surfaces (try values 3/4, 1/2 of dab, or even 1/4) |
259 d:= dab; |
264 d:= dab * 100 div dabDiv; |
|
265 //d:= dab * (1 + abs(cFeatureSize - 8)) div 6; |
|
266 //d:= dab * (14 + cFeatureSize) div 20; |
260 if distL > d then distL:= d; |
267 if distL > d then distL:= d; |
261 if distR > d then distR:= d; |
268 if distR > d then distR:= d; |
262 |
269 |
263 if distR + distL < minDistance * 2 + 10 then |
270 if distR + distL < minDistance * 2 + 10 then |
264 begin |
271 begin |
334 fps:=Template.FillPoints^; |
341 fps:=Template.FillPoints^; |
335 ResizeLand(Template.TemplateWidth, Template.TemplateHeight); |
342 ResizeLand(Template.TemplateWidth, Template.TemplateHeight); |
336 for y:= 0 to LAND_HEIGHT - 1 do |
343 for y:= 0 to LAND_HEIGHT - 1 do |
337 for x:= 0 to LAND_WIDTH - 1 do |
344 for x:= 0 to LAND_WIDTH - 1 do |
338 Land[y, x]:= lfBasic; |
345 Land[y, x]:= lfBasic; |
339 |
346 |
|
347 minDistance:= sqr(cFeatureSize) div 8 + 10; |
|
348 //dabDiv:= getRandom(41)+60; |
|
349 //dabDiv:= getRandom(31)+70; |
|
350 dabDiv:= getRandom(21)+100; |
340 MaxHedgehogs:= Template.MaxHedgehogs; |
351 MaxHedgehogs:= Template.MaxHedgehogs; |
341 hasGirders:= Template.hasGirders; |
352 hasGirders:= Template.hasGirders; |
342 playHeight:= Template.TemplateHeight; |
353 playHeight:= Template.TemplateHeight; |
343 playWidth:= Template.TemplateWidth; |
354 playWidth:= Template.TemplateWidth; |
344 leftX:= (LAND_WIDTH - playWidth) div 2; |
355 leftX:= (LAND_WIDTH - playWidth) div 2; |
345 rightX:= Pred(leftX + playWidth); |
356 rightX:= Pred(leftX + playWidth); |
346 topY:= LAND_HEIGHT - playHeight; |
357 topY:= LAND_HEIGHT - playHeight; |
347 |
358 |
348 {$HINTS OFF} |
359 {$HINTS OFF} |
349 SetPoints(Template, pa, @fps); |
360 SetPoints(Template, pa, @fps); |
350 {$HINTS ON} |
361 {$HINTS ON} |
351 |
362 |
352 Distort2(Template, @fps, pa); |
363 Distort2(Template, @fps, pa); |