1 /* WMGlobe 1.3 - All the Earth on a WMaker Icon
2 * copyright (C) 1998,99,2000,01 Jerome Dumonteil <jerome.dumonteil@linuxfr.org>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 ***************************************************************************/
18 /* this code was based on XGlobe :
21 * This file is part of XGlobe. See README for details.
23 * Copyright (C) 1998 Thorsten Scheuermann
25 * This program is free software; you can redistribute it and/or modify
26 * it under the terms of the GNU General Public Licenses as published by
27 * the Free Software Foundation.
28 ************************************************************************/
30 Some parts of this files should be rewritten to not depend on
36 static RColor mygetMapColorLinear
37 (double longitude
, double latitude
, double angle
);
40 * static RColor getMapColor(double longitude, double latitude, double angle);
43 static void randomPosition();
44 void setViewPos(double lat
, double lon
);
45 static void myRPutPixel(int x
, int y
, RColor
* color
);
47 #if (WITH_MARKERS == 1)
48 static void invertPixel(int x
, int y
);
49 static void put_cross(int x
, int y
);
50 static void put_dot_cross(int x
, int y
, RColor
* color
);
53 static void getquarter(RImage
* image
, int x
, int y
, MPO
* m
[4], int dx
,
55 static void updateTime(int force
);
56 static struct timeval
timeaccel(struct timeval t
);
63 struct timeval
timeaccel(struct timeval t
)
68 t
= diftimev(t
, tini
);
69 rr
= floor((double) t
.tv_sec
* time_multi
+
70 (double) t
.tv_usec
* time_multi
/ 1000000.);
71 /*** something bad may appen if time_multi=max after 41 minutes (overflow) ***/
72 while (rr
> (double) LONG_MAX
)
73 rr
-= (2.0 * (double) LONG_MAX
+ 1.0);
75 at
.tv_usec
= (int) (t
.tv_usec
* time_multi
) % 1000000;
76 return addtimev(at
, tbase
);
84 static void myRPutPixel(int x
, int y
, RColor
* color
)
87 unsigned char *sr
, *sg
, *sb
;
89 ofs
= (y
* DIAMETRE
+ x
) * 3;
90 sr
= small
->data
+ (ofs
++);
91 sg
= small
->data
+ (ofs
++);
92 sb
= small
->data
+ (ofs
);
106 static void invertPixel(int x
, int y
)
109 unsigned char *sr
, *sg
, *sb
;
111 ofs
= (y
* DIAMETRE
+ x
) * 3;
112 sr
= small
->data
+ (ofs
++);
113 sg
= small
->data
+ (ofs
++);
114 sb
= small
->data
+ (ofs
);
116 #if ( CROSS_INVERT == 1 )
121 if (*sb
> 127 || *sg
> 127 || *sr
> 127)
124 *sr
= *sg
= *sb
= 255;
129 #define T_CADRE(x,y) ((x) < DIAMETRE && (x) >= 0 \
130 && (y) < DIAMETRE && (y) >= 0 && tabsolu[(x)][(y)])
136 static void put_cross(int x
, int y
)
138 int i
, x_cross
, y_cross
;
141 if (!fun
&& sens
!= 1) {
142 x
= DIAMETRE
- 1 - x
;
143 y
= DIAMETRE
- 1 - y
;
145 for (i
= 2; i
<= CROSS_LENGTH
; i
++) {
148 if (T_CADRE(x_cross
, y_cross
))
149 invertPixel(x_cross
, y_cross
);
152 if (T_CADRE(x_cross
, y_cross
))
153 invertPixel(x_cross
, y_cross
);
156 if (T_CADRE(x_cross
, y_cross
))
157 invertPixel(x_cross
, y_cross
);
160 if (T_CADRE(x_cross
, y_cross
))
161 invertPixel(x_cross
, y_cross
);
173 static void put_dot_cross(int x
, int y
, RColor
* color
)
175 int i
, x_cross
, y_cross
;
178 if (!fun
&& sens
!= 1) {
179 x
= DIAMETRE
- 1 - x
;
180 y
= DIAMETRE
- 1 - y
;
182 for (i
= 2; i
<= CROSS_LENGTH
; i
+= 2) {
185 if (T_CADRE(x_cross
, y_cross
))
186 invertPixel(x_cross
, y_cross
);
189 if (T_CADRE(x_cross
, y_cross
))
190 invertPixel(x_cross
, y_cross
);
193 if (T_CADRE(x_cross
, y_cross
))
194 invertPixel(x_cross
, y_cross
);
197 if (T_CADRE(x_cross
, y_cross
))
198 invertPixel(x_cross
, y_cross
);
202 if (T_CADRE(x_cross
, y_cross
))
203 myRPutPixel(x_cross
, y_cross
, color
);
206 if (T_CADRE(x_cross
, y_cross
))
207 myRPutPixel(x_cross
, y_cross
, color
);
210 if (T_CADRE(x_cross
, y_cross
))
211 myRPutPixel(x_cross
, y_cross
, color
);
214 if (T_CADRE(x_cross
, y_cross
))
215 myRPutPixel(x_cross
, y_cross
, color
);
228 static void getquarter(RImage
* image
, int x
, int y
, MPO
* m
[4], int dx
,
234 /*** hope this is faster than calculation with floats .... ****/
239 ofs
= (y
* image
->width
+ x
) * 3;
240 m
[0]->r
= image
->data
[ofs
++];
241 m
[0]->g
= image
->data
[ofs
++];
242 m
[0]->b
= image
->data
[ofs
];
246 ofs
= (y
* image
->width
+ xx
) * 3;
247 m
[1]->r
= image
->data
[ofs
++];
248 m
[1]->g
= image
->data
[ofs
++];
249 m
[1]->b
= image
->data
[ofs
];
253 ofs
= (y
* image
->width
+ x
) * 3;
254 m
[2]->r
= image
->data
[ofs
++];
255 m
[2]->g
= image
->data
[ofs
++];
256 m
[2]->b
= image
->data
[ofs
];
258 ofs
= (y
* image
->width
+ xx
) * 3;
259 m
[3]->r
= image
->data
[ofs
++];
260 m
[3]->g
= image
->data
[ofs
++];
261 m
[3]->b
= image
->data
[ofs
];
265 * m[0]->r=((m[0]->r*(256-dx)*(256-dy))+
266 * (m[1]->r*dx*(256-dy))+
267 * (m[2]->r*(256-dx)*dy)+
268 * (m[3]->r*dx*dy))>>16;
269 * m[0]->g=((m[0]->g*(256-dx)*(256-dy))+
270 * (m[1]->g*dx*(256-dy))+
271 * (m[2]->g*(256-dx)*dy)+
272 * (m[3]->g*dx*dy))>>16;
273 * m[0]->b=((m[0]->b*(256-dx)*(256-dy))+
274 * (m[1]->b*dx*(256-dy))+
275 * (m[2]->b*(256-dx)*dy)+
276 * (m[3]->b*dx*dy))>>16;
279 if ((ofs
= m
[1]->r
- m
[0]->r
) != 0)
280 m
[0]->r
+= (ofs
* dx
) >> 8;
281 if ((ofs
= m
[1]->g
- m
[0]->g
) != 0)
282 m
[0]->g
+= (ofs
* dx
) >> 8;
283 if ((ofs
= m
[1]->b
- m
[0]->b
) != 0)
284 m
[0]->b
+= (ofs
* dx
) >> 8;
286 if ((ofs
= m
[3]->r
- m
[2]->r
) != 0)
287 m
[2]->r
+= (ofs
* dx
) >> 8;
288 if ((ofs
= m
[3]->g
- m
[2]->g
) != 0)
289 m
[2]->g
+= (ofs
* dx
) >> 8;
290 if ((ofs
= m
[3]->b
- m
[2]->b
) != 0)
291 m
[2]->b
+= (ofs
* dx
) >> 8;
293 if ((ofs
= m
[2]->r
- m
[0]->r
) != 0)
294 m
[0]->r
+= (ofs
* dy
) >> 8;
295 if ((ofs
= m
[2]->g
- m
[0]->g
) != 0)
296 m
[0]->g
+= (ofs
* dy
) >> 8;
297 if ((ofs
= m
[2]->b
- m
[0]->b
) != 0)
298 m
[0]->b
+= (ofs
* dy
) >> 8;
315 tan_a
= (zoom
* DIAMETRE
/ 2.0) / proj_dist
;
317 * distance of camera to center of earth ( = coordinate origin)
319 center_dist
= radius
/ sin(atan(tan_a
));
320 c_coef
= center_dist
* center_dist
- radius
* radius
;
338 double dir_x
, dir_y
, dir_z
; /* direction of cast ray */
340 double hit_x
, hit_y
, hit_z
; /* hit position on earth surface */
342 double hit2_x
, hit2_y
, hit2_z
; /* mirrored hit position on earth surface */
344 double sp_x
, sp_y
, sp_z
; /* intersection point of globe and ray */
346 double a
; /* coeff. of quardatic equation */
348 double udroot
; /* racine */
352 double s1
, s2
, s
; /*distance between intersections and
355 double longitude
, latitude
; /* coordinates of hit position */
357 double light_angle
; /* cosine of angle between sunlight and
360 int startx
, endx
; /* the region to be painted */
374 a
= dir_x
= dir_y
= 0;
378 fprintf(stdout
, "solution : %d\n", solution
);
383 if (solution
== FALSE
)
384 RClearImage(small
, &noir
);
400 * calc. radius of projected sphere
402 if (solution
== FALSE
) {
403 b_coef
= 2 * center_dist
* dir_z
;
405 (int) sqrt(b_coef
* b_coef
/ (4 * c_coef
) - dir_z
* dir_z
) + 1;
409 starty
= DIAMETRE
/ 2 - radius_proj
- 3;
410 endy
= DIAMETRE
- starty
- 1;
411 if ((double) starty
< (double) (-funy
))
413 if ((double) starty
> (double) (DIAMETRE
- 1 - funy
))
414 starty
= DIAMETRE
- 1 - funy
;
415 if ((double) endy
< (double) (-funy
))
417 if ((double) endy
> (double) (DIAMETRE
- 1 - funy
))
418 endy
= DIAMETRE
- 1 - funy
;
420 if (solution
== FALSE
) {
422 if (starty
+ funy
> 0)
423 for (j
= 0; j
< starty
+ funy
; j
++)
424 for (i
= 0; i
< DIAMETRE
; i
++)
426 if (endy
+ 1 + funy
<= DIAMETRE
- 1)
427 for (j
= endy
+ funy
+ 1; j
< DIAMETRE
; j
++)
428 for (i
= 0; i
< DIAMETRE
; i
++)
432 for (py
= starty
; py
<= endy
; py
++) {
434 startx
= DIAMETRE
/ 2 - 6 -
435 (int) sqrt(MAX((radius_proj
* radius_proj
-
436 (py
- DIAMETRE
/ 2) *
437 (py
- DIAMETRE
/ 2)), 0.0));
439 endx
= DIAMETRE
- startx
- 1;
440 if ((double) startx
< (double) (-funx
))
443 if ((double) startx
> (double) (DIAMETRE
- 1 - funx
))
444 startx
= DIAMETRE
- 1 - funx
;
446 if ((double) endx
< (double) (-funx
))
448 if ((double) endx
> (double) (DIAMETRE
- 1 - funx
))
449 endx
= DIAMETRE
- 1 - funx
;
451 if (solution
== FALSE
) {
453 if (startx
+ funx
> 0)
454 for (i
= 0; i
< startx
+ funx
; i
++)
455 tabsolu
[i
][py
+ funy
] = 0;
456 if (endx
+ 1 + funx
<= DIAMETRE
- 1)
457 for (i
= endx
+ 1 + funx
; i
< DIAMETRE
; i
++)
458 tabsolu
[i
][py
+ funy
] = 0;
463 * calculate offset into image data
466 for (px
= startx
; px
<= endx
; px
++) {
467 if (solution
== FALSE
) {
468 dir_x
= (double) px
- DIAMETRE
/ 2 + 0.5;
469 dir_y
= -(double) py
+ DIAMETRE
/ 2 - 0.5;
471 a
= dir_x
* dir_x
+ dir_y
* dir_y
+ dir_z
* dir_z
;
473 udroot
= b_coef
* b_coef
- 4 * a
* c_coef
; /*what's under the
474 sq.root when solving the quadratic equation */
476 tabsolu
[px
+ funx
][py
+ funy
] = 1;
477 wurzel
= sqrt(udroot
);
478 s1
= (-b_coef
+ wurzel
) / (2. * a
);
479 s2
= (-b_coef
- wurzel
) / (2. * a
);
480 s
= (s1
< s2
) ? s1
: s2
; /* smaller solution belongs
481 to nearer intersection */
482 solu
[px
+ funx
][py
+ funy
][0] = s
* dir_x
;
483 solu
[px
+ funx
][py
+ funy
][1] = s
* dir_y
;
484 solu
[px
+ funx
][py
+ funy
][2] =
485 center_dist
+ s
* dir_z
;
487 tabsolu
[px
+ funx
][py
+ funy
] = 0;
491 if (tabsolu
[px
+ funx
][py
+ funy
]) { /* solution exists <=>
492 intersection exists */
493 sp_x
= solu
[px
+ funx
][py
+ funy
][0]; /* sp = camera pos + s*dir */
494 sp_y
= solu
[px
+ funx
][py
+ funy
][1];
495 sp_z
= solu
[px
+ funx
][py
+ funy
][2];
497 hit_x
= m11
* sp_x
+ m12
* sp_y
+ m13
* sp_z
;
498 hit_y
= m22
* sp_y
+ m23
* sp_z
;
499 hit_z
= m31
* sp_x
+ m32
* sp_y
+ m33
* sp_z
;
501 hit2_x
= -m11
* sp_x
+ m12
* sp_y
+ m13
* sp_z
;
502 hit2_y
= m22
* sp_y
+ m23
* sp_z
;
503 hit2_z
= -m31
* sp_x
+ m32
* sp_y
+ m33
* sp_z
;
504 /*** hope hit_z wont get too close to zero *******/
505 if (ABS(hit_z
) < 0.001) {
506 if (hit_x
* hit_z
> 0.)
509 longitude
= -PI
/ 2.;
515 longitude
= atan(hit_x
/ hit_z
);
521 r
= (double) sqrt(hit_x
* hit_x
+ hit_z
* hit_z
);
523 latitude
= atan(-hit_y
/ r
);
526 (light_x
* hit_x
+ light_y
* hit_y
+
527 light_z
* hit_z
) / radius
;
534 mygetMapColorLinear(longitude
, latitude
,
536 /* here dont use myRPutPixel since we prefer some
537 error detection about limits */
538 RPutPixel(small
, px
+ funx
, py
+ funy
, &teinte
);
548 starty
= DIAMETRE
/ 2 - radius_proj
- 3;
549 starty
= (starty
< 0) ? 0 : starty
;
550 endy
= DIAMETRE
- starty
- 1;
554 if (solution
== FALSE
) {
557 for (j
= 0; j
< starty
; j
++)
558 for (i
= 0; i
< DIAMETRE
; i
++)
560 if (endy
+ 1 <= DIAMETRE
- 1)
561 for (j
= endy
+ 1; j
< DIAMETRE
; j
++)
562 for (i
= 0; i
< DIAMETRE
; i
++)
567 for (py
= starty
; py
<= endy
; py
++) {
568 startx
= DIAMETRE
/ 2 - 6 -
569 (int) sqrt(MAX((radius_proj
* radius_proj
-
570 (py
- DIAMETRE
/ 2) *
571 (py
- DIAMETRE
/ 2)), 0.0));
572 startx
= (startx
< 0) ? 0 : startx
;
576 if (solution
== FALSE
) {
579 for (i
= 0; i
< startx
; i
++) {
581 tabsolu
[DIAMETRE
- 1 - i
][py
] = 0;
585 for (px
= startx
; px
< DIAMETRE
/ 2; px
++) {
586 if (solution
== FALSE
) {
587 dir_x
= (double) px
- DIAMETRE
/ 2 + 0.5;
589 dir_y
= -(double) py
+ DIAMETRE
/ 2 - 0.5;
591 a
= dir_x
* dir_x
+ dir_y
* dir_y
+ dir_z
* dir_z
;
593 /*what's under the sq.root when solving the
594 quadratic equation */
595 udroot
= b_coef
* b_coef
- 4 * a
* c_coef
;
598 tabsolu
[DIAMETRE
- 1 - px
][py
] = 1;
599 wurzel
= sqrt(udroot
);
600 s1
= (-b_coef
+ wurzel
) / (2. * a
);
601 s2
= (-b_coef
- wurzel
) / (2. * a
);
602 s
= (s1
< s2
) ? s1
: s2
; /* smaller solution
605 /* sp = camera pos + s*dir */
606 solu
[px
][py
][0] = s
* dir_x
;
607 solu
[px
][py
][1] = s
* dir_y
;
608 solu
[px
][py
][2] = center_dist
+ s
* dir_z
;
611 tabsolu
[DIAMETRE
- 1 - px
][py
] = 0;
614 if (tabsolu
[px
][py
]) { /* solution exists <=>
615 intersection exists */
616 sp_x
= solu
[px
][py
][0];
617 sp_y
= solu
[px
][py
][1];
618 sp_z
= solu
[px
][py
][2];
619 hit_x
= m11
* sp_x
+ m12
* sp_y
+ m13
* sp_z
;
620 hit_y
= m22
* sp_y
+ m23
* sp_z
;
621 hit_z
= m31
* sp_x
+ m32
* sp_y
+ m33
* sp_z
;
623 hit2_x
= -m11
* sp_x
+ m12
* sp_y
+ m13
* sp_z
;
624 hit2_y
= m22
* sp_y
+ m23
* sp_z
;
625 hit2_z
= -m31
* sp_x
+ m32
* sp_y
+ m33
* sp_z
;
627 /*** hope hit_z wont get too close to zero *******/
629 if (ABS(hit_z
) < ABS(minhz
)) {
631 fprintf(stdout
, "should >>0 : hit_z %f\n", hit_z
);
632 fprintf(stdout
, " hit_x %f\n", hit_x
);
633 fprintf(stdout
, " ratio %f\n",
635 fprintf(stdout
, " long %f\n",
636 atan(hit_x
/ hit_z
));
641 if (ABS(hit_z
) < 0.001) {
642 if (hit_x
* hit_z
> 0.)
645 longitude
= -PI
/ 2.;
651 longitude
= atan(hit_x
/ hit_z
);
657 r
= (double) sqrt(hit_x
* hit_x
+ hit_z
* hit_z
);
659 latitude
= atan(-hit_y
/ r
);
662 (light_x
* hit_x
+ light_y
* hit_y
+
663 light_z
* hit_z
) / radius
;
671 mygetMapColorLinear(longitude
, latitude
,
673 myRPutPixel(px
, py
, &teinte
);
676 * mirror the left half-circle of the globe:
677 * we need a new position and have to recalc. the
682 (light_x
* hit2_x
+ light_y
* hit2_y
+
683 light_z
* hit2_z
) / radius
;
685 mygetMapColorLinear(2 * v_long
- longitude
,
686 latitude
, light_angle
);
687 myRPutPixel(DIAMETRE
- px
- 1, py
, &teinte
);
695 mygetMapColorLinear(longitude
, latitude
,
697 myRPutPixel(DIAMETRE
- px
- 1, DIAMETRE
- py
- 1,
701 * mirror the left half-circle of the globe:
702 * we need a new position and have
703 * to recalc. the light intensity
707 (light_x
* hit2_x
+ light_y
* hit2_y
+
708 light_z
* hit2_z
) / radius
;
710 mygetMapColorLinear(2 * v_long
- longitude
,
711 latitude
, light_angle
);
712 myRPutPixel(px
, DIAMETRE
- py
- 1, &teinte
);
726 for (i
= 0; i
< nb_marker
; i
++) {
728 mx
= m11
* marker
[i
][0] + m31
* marker
[i
][2];
729 mz
= -m31
* marker
[i
][0] + m11
* marker
[i
][2];
730 my
= m22
* marker
[i
][1] - m23
* mz
;
731 mz
= m23
* marker
[i
][1] + m22
* mz
;
734 if (i
== sun_marker
) {
736 (mx
* radius_proj
+ DIAMETRE
/ 2 + funx
),
737 (int) (-my
* radius_proj
+ DIAMETRE
/ 2 +
739 } else if (i
== moon_marker
) {
741 (mx
* radius_proj
+ DIAMETRE
/ 2 + funx
),
742 (int) (-my
* radius_proj
+ DIAMETRE
/ 2 +
746 (mx
* radius_proj
+ DIAMETRE
/ 2 + funx
),
747 (int) (-my
* radius_proj
+ DIAMETRE
/ 2 +
771 mygetMapColorLinear(double longitude
, double latitude
, double angle
)
774 int x
, y
, xl
, yl
, dx
, dy
, ang
;
782 if (longitude
>= 2 * PI
)
786 ang
= (int) floor((1 - ((1 - angle
) * dawn
)) * 256);
790 xl
= (int) (longitude
* mratiox
);
791 yl
= (int) (latitude
* mratioy
);
800 getquarter(map
, x
, y
, md
, dx
, dy
);
801 getquarter(mapnight
, x
, y
, mn
, dx
, dy
);
803 md
[0]->r
= ((mn
[0]->r
* (256 - ang
) + md
[0]->r
* ang
)) >> 8;
804 md
[0]->g
= ((mn
[0]->g
* (256 - ang
) + md
[0]->g
* ang
)) >> 8;
805 md
[0]->b
= ((mn
[0]->b
* (256 - ang
) + md
[0]->b
* ang
)) >> 8;
807 getquarter(mapnight
, x
, y
, md
, dx
, dy
);
810 getquarter(map
, x
, y
, md
, dx
, dy
);
814 md
[0]->r
* ang
/ 256 * (256 - aml
))) >> 8;
817 md
[0]->g
* ang
/ 256 * (256 - aml
))) >> 8;
820 md
[0]->b
* ang
/ 256 * (256 - aml
))) >> 8;
822 md
[0]->r
= (md
[0]->r
* aml
) >> 8;
823 md
[0]->g
= (md
[0]->g
* aml
) >> 8;
824 md
[0]->b
= (md
[0]->b
* aml
) >> 8;
828 point
.red
= (unsigned char) md
[0]->r
;
829 point
.green
= (unsigned char) md
[0]->g
;
830 point
.blue
= (unsigned char) md
[0]->b
;
831 point
.alpha
= 255; /* in fun mode, we use original Rputpixel that need alpha?*/
841 static void randomPosition()
843 addlat
= ((rand() % 30001) / 30000.) * 180. - 90.;
844 addlong
= ((rand() % 30001) / 30000.) * 360. - 180.;
856 static void updateTime(int force
)
858 /* calcul of sun position every minute */
859 if ((trend
.tv_sec
- tsunpos
) >= 60 || force
) {
860 tsunpos
= trend
.tv_sec
;
861 sun_position(tsunpos
, &sun_lat
, &sun_long
);
862 light_x
= cos(sun_lat
) * sin(sun_long
);
863 light_y
= sin(sun_lat
);
864 light_z
= cos(sun_lat
) * cos(sun_long
);
867 if (sun_marker
>= 0) {
868 marker
[sun_marker
][0] = light_x
;
869 marker
[sun_marker
][1] = light_y
;
870 marker
[sun_marker
][2] = light_z
;
872 /* ... and the moon position */
873 if (moon_marker
>= 0 || p_type
== PTMOON
|| force
== STRONG
) {
874 moon_position(tsunpos
, &moon_lat
, &moon_long
);
875 if (moon_marker
>= 0) {
876 marker
[moon_marker
][1] = moon_lat
;
877 marker
[moon_marker
][0] = moon_long
;
878 transform_marker(moon_marker
);
894 void transform_marker(int m
)
896 /* long/lat => rotation matrix */
899 dtmp1
= sin(marker
[m
][0]) * cos(marker
[m
][1]);
900 dtmp2
= sin(marker
[m
][1]);
901 marker
[m
][2] = cos(marker
[m
][0]) * cos(marker
[m
][1]);
902 marker
[m
][0] = dtmp1
;
903 marker
[m
][1] = dtmp2
;
913 void setViewPos(double lat
, double lon
)
920 while (addlat
>= 360.)
922 while (addlat
<= -360.)
928 addlat
+= (lat
- dif
);
930 if (!fun
&& !stable
) {
940 addlat
+= (lat
- dif
);
942 if (!fun
&& !stable
) {
952 addlat
+= (lat
- dif
);
954 if (!fun
&& !stable
) {
964 addlat
+= (lat
- dif
);
966 if (!fun
&& !stable
) {
973 while (lon
>= 180.) {
977 while (lon
<= -180.) {
982 v_lat
= lat
* PI
/ 180.;
983 v_long
= lon
* PI
/ 180.;
997 void recalc(int force
)
999 double coeff
, va
, vo
;
1000 struct timeval tv
, tnow
;
1003 trend
= timeaccel(tnow
);
1004 tv
= diftimev(tnow
, tlast
);
1010 coeff
= (double) tv
.tv_sec
+ tv
.tv_usec
/ 1000000.;
1013 /** while !clic button rotate earth **/
1014 addlat
+= dlat
* coeff
;
1015 addlong
+= dlong
* coeff
;
1019 if (addlong
!= old_dvlong
|| addlat
!= old_dvlat
|| p_type
== PTRANDOM
) {
1020 old_dvlong
= addlong
;
1022 do_something
= TRUE
;
1026 if (p_type
== PTSUN
) {
1027 va
= sun_lat
* 180. / PI
;
1028 vo
= sun_long
* 180. / PI
;
1030 addlat
-= sun_lat
* 180. / PI
- va
;
1031 addlong
-= sun_long
* 180. / PI
- vo
;
1032 } else if (p_type
== PTMOON
) {
1033 va
= moon_lat
* 180. / PI
;
1034 vo
= moon_long
* 180. / PI
;
1036 addlat
-= moon_lat
* 180. / PI
- va
;
1037 addlong
-= moon_long
* 180. / PI
- vo
;
1040 if (force
&& p_type
== PTSUN
) {
1041 va
= sun_lat
* 180. / PI
;
1042 vo
= sun_long
* 180. / PI
;
1044 addlat
-= sun_lat
* 180. / PI
- va
;
1045 addlong
-= sun_long
* 180. / PI
- vo
;
1054 setViewPos(sun_lat
* 180. / PI
+ addlat
,
1055 sun_long
* 180. / PI
+ addlong
);
1060 setViewPos(moon_lat
* 180. / PI
+ addlat
,
1061 moon_long
* 180. / PI
+ addlong
);
1065 setViewPos(addlat
, addlong
);
1069 if (stoprand
== FALSE
)
1073 setViewPos(addlat
, addlong
);
1080 fprintf(stdout
, "%s render\n", ctime(&trend
.tv_sec
));
1085 tnext
= addtimev(tnow
, tdelay
);
1095 /* convert a 4 layers RGBA image to a 3 layer one */
1096 int ripalpha(RImage
* image
)
1099 unsigned char *d
, *s
, *old
;
1103 if (image
->format
== RRGBFormat
)
1106 d
= malloc(image
->width
* image
->height
* 3 + 4);
1108 RErrorCode
= RERR_NOMEMORY
;
1109 puts("error in ripalpha");
1116 image
->format
= RRGBFormat
;
1117 for (y
= 0; y
< image
->height
; y
++) {
1118 for (x
= 0; x
< image
->width
; x
++) {