-
Notifications
You must be signed in to change notification settings - Fork 1
/
Protected_crossing_fr.scad
2603 lines (2396 loc) · 90.5 KB
/
Protected_crossing_fr.scad
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
//// Protected crossing design
// Copyright 2018 Pierre ROUZEAU AKA PRZ
// Program license GPL v3
// documentation licence cc BY-SA 4.0 and GFDL 1.2
// First version: 0.0 - 19 August 2018
// V 0.1: 22 August 2018 - bugs, generic vehicles, always bike advanced position, protective poles, precise light positioning.
// V 0.2: 28 August 2018 - bugs, own models, more checks, misc. improvements.
// V 0.5: 11 sept 2018 Adjustable swerve angle. Manual improvements. Misc. cleanup.
//All designs done with this application are free of right
// This uses my OpenSCAD library, attached, but you can find details here:
// https://github.com/PRouzeau/OpenScad-Library
//Bus model own design, 12 x 2.55 m, wheel base 5.9 m.
//bike model own design
//car model length 4.2 m
//ground marking bikes own design
/*Please note that a complete help (in english and in french) is available:
*On Internet at http://rouzeau.net/pcross
*Or directly in the help directory by running the 'index.htm' file. This is direct with Firefox or Edge but Chrome refuse to execute local Javascript files and you will need to use a local web server or to create a new shortcut with the parameter "--allow-file-access-from-files".
*/
/* KNOWN BUGS:
*When there is an alley and the pavement separation is not sufficiently wide, the main traffic light position may not be correct
*Islands have problems if there is no bikeway on one side
*If there is too much assysmetry in the road (e.g. one pavement is much larger than the other), there could be troubles on the island
*When there is no deviation in lane because there is no bikeway on that side, but a deviation exists on the other side to reach the corner, the stop line don't start at the good position and part is missing
*If there is an alley not used for cycle path and a cycle lane, all crossing is wrong
*If the alley is not dedicated to cycle path, there are some misplaced pavements.
*The roundabout ground marking assumes symetrical lanes layout, which is not necessarily the case, you can have two inlet for one outlet.
*Double direction path have many problems and yet are not properly working. Parking lane shall be on the other side than the double cirection bike path.Islands are lost
Generally speaking, turns and ground marking are not handled well on double direction bike paths
Bikeway are not handled properly when there is a t cross and a double direction cycle path on the side of the t branch (there shall not be traversing bikeways)
*/
/*
Conception de croisement protégés 'à la néerlandaise'
Pour une explication de l'état de l'art, voyez le lien (en anglais):
https://bicycledutch.wordpress.com/2011/04/07/state-of-the-art-bikeway-design-or-is-it/
Voir d'abord le fichier Lisez_moi.txt
Le fichier 'Presentation_fr.txt' donne un point de vue plus général sur la conception de cette application.
Seuls les versions de développement 'snapshot versions' d'OpenScad comportent Customizer, utilisez la dernière version (actuellemrnt le 1 Juin 2018)
Vous DEVEZ activer Customizer:
*Menu [Edition], selectionner [Préférences] puis ouvrir l'onglet [Fonctionnalités], cocher [Customizer], puis fermer la fenêtre.
*Dans le menu [Vues], vous devez désormais avoir une option [Hide customizer], que vous devez décocher.
*Dans l'écran de Customizer (pas encore traduit), sur la première ligne, sélectionner [Description only], ce qui fera une interface nettement plus sobre.
*Éventuellement vous fermerez la fenêtre d'édition avec le menu [Vues], option [Cacher l'éditeur].
*L'interface est par défaut dans le langage local (tel que configuré sur votrre ordinateur). Pour désactiver: menu [Edition][Préférences], onglet [Avancé], décocher l'option (en bas) [Activer la localisation de l'interface utilisateur (nécessite un redémarrage d'openSCAD)].
Quand vous êtes content de votre conception, vous pouvez l'enregister comme un 'dataset', utilisez le bouton [+] pour créer un nouveau dataset puis [save preset] pour les enregistrements ultérieurs, que vous pourrez rappeler plus tard en la sélectionnant dans le menu déroulant. RIEN n'est sauvegardé automatiquement.
Notez que pour les variables avec des flèches de modifications, quand vous cliquez sur le champ, vous pouvez alors modifier la valeur avec la roulette de la souris.
notez les conventions
0 neutralise les équipments
n un nombre donne une valeur
Repérage (conforme au repère OpenScad):
Route X gauche droite
Route Y nord-sud
Pour chaque route il y a deux branches, A et B, mais il peut y avoir des paramètres communs a ces branches (voir plus loin).
Les dimensions sont en m
Utilisation:
La toute première chose que vous souhaitez, c'est de pouvoir manipuler l'image en trois dimensions sans voir celle-ci revenir à sa position par défaut a chaque calcul, ouvrez (dans customizer) l'onglet [Caméra] et décocher [Imposer la position de la caméra].
Après ceci, vous êtes libre de modifier toute variable pour ajuster votre conception de croisement. Souvenez-vous que rien n'est sauvegardé tant que vous n'avez pas enregistré de 'dataset'.
BOGUES CONNUS:
Voir en anglais plus loin
*/
/*
Developer note:
For translation utility, I made a Libre office macro, that you can find in separated file. See also my request here:
https://github.com/openscad/openscad/issues/2434
todo:
*Bike path in an alley not using the whole alley - may be difficult and can broke the dataset
*Allow differentiated opposite branch
*Expand the checking procedures
It shall be noted that height is used for ground marking, road surface, etc. to define what will be visible and priorities. All these is lost when projecting and you have a lot of normally invisible lines. It might be better to export an image and use image treatment, however the major advantage of projection is its capability to export dxf files.
To avoid Openscad artifacts, some elements have levels differentiated by a few mm (there are 'mirages' when substracting parts with same top or bottom levels).
*/
//*********************************
include <Z_library.scad>
include <Road_signs.scad>
/*[Hidden]*/
$fn=32;
glass_color = [128,128,128,180]/256;
// transparent
debug=true;
//y road B side in continuity with A
XB_totwidth=0;
YB_totwidth=0;
XBr_pedcross_shift=0;
YBr_pedcross_shift=0;
XBr_pedcross_wd=0;
YBr_pedcross_wd=0;
/*[_Reserved-do not modify] not to be modified by user*/
//Merci de ne pas modifier les variables de cet onglet
//_=true;
//Version
pcross_version = 1;
//language
language = "fr";
//Coefficient d'unités principal, natif en mm, interface en m
cfu=1000;
//Coefficient d'unités pour les lignes
cfu_line=1;
//===================================
/*[Caméra]*/
//Imposer la position de la caméra
Dictate_camera_position=true;
// The camera variables shall NOT be included in a module - a module CANNOT export variables
//Vue de dessus
Top_view = false;
//Distance de la caméra
Cimp = Dictate_camera_position||Top_view;
$vpd=Cimp?Top_view?220000:110000:$vpd;
//Vecteur de déplacement
$vpt=Cimp?[1150,900,700]:$vpt;
//Vecteur de rotation
$vpr=Cimp?Top_view?[0,0,0]:[64,0,19]:$vpr;
//echo_camera();
//================================
/*[Affichage]*/
/*
//Affiche batiments (pas encore installé)
display_building = false;
*/
//Projection (pour exportation fichier dxf)
Projection=false;
//Affiche la route (sinon seulement trottoirs et marquage)
Display_road = true;
//Affiche avertissements et données dans la vues 3D
Disp_text = true;
//Affiche avertissements dans la console
inf_text = true;
//Afficher les véhicules
vh_disp = false;
//== VEHICLES ===================
//see in vehicle chapter v_color and v_type for color and vehicle association
/*[Véhicules]*/
//-- Vehicle 1 -------------------
//Type du véhicule 1 à afficher
vh1_type = 1; // [0:"Aucun",1:"Voiture rouge",2:"Voiture bleue",3:"Bus",4:"Cycliste"]
//Éléments accessoires du véhicule 1
vh1_acc = 1; // [0:"None",1:"Vehicle line limit X (for cars)",2:"Vehicle line limit Y (for cars)",3:"Arrow",4:"Views angles"]
//::vh1_acc = 0; // [0:"Sans",1:"Limite du véhicule ligne X",2:"Limite du véhicule ligne Y",3:"Flèche",4:"Angles de vision"]
//Véhicule 1 position en X
vh1_X = 2.8; //[-22:0.1:22]
//Véhicule 1 position en Y
vh1_Y = 6; //[-22:0.1:22]
//Véhicule 1 angle
vh1_ang = 115;
//-- Vehicle 2 -------------------
//Type du véhicule 2 à afficher
vh2_type = 2; // [0:"Aucun",1:"Voiture rouge",2:"Voiture bleue",3:"Bus",4:"Cycliste"]
//Éléments accessoires du véhicule 2
vh2_acc = 0; // [0:"None",1:"Vehicle line limit X (for cars)",2:"Vehicle line limit Y (for cars)",3:"Arrow",4:"Views angles"]
//::vh2_acc = 0; // [0:"Sans",1:"Limite du véhicule ligne X",2:"Limite du véhicule ligne Y",3:"Flèche",4:"Angles de vision"]
//Véhicule 2 position en X
vh2_X = 8; //[-22:0.1:22]
//Véhicule 2 position en Y
vh2_Y = 2.5; //[-22:0.1:22]
//Véhicule 2 angle
vh2_ang = 180;
//-- Vehicle 3 -------------------
//Type du véhicule 3 à afficher
vh3_type = 3; // [0:"Aucun",1:"Voiture rouge",2:"Voiture bleue",3:"Bus",4:"Cycliste"]
//Éléments accessoires du véhicule 3
vh3_acc = 0; // [0:"None",1:"Vehicle line limit X (for cars)",2:"Vehicle line limit Y (for cars)",3:"Arrow",4:"Views angles"]
//::vh3_acc = 0; // [0:"Sans",1:"Limite du véhicule ligne X",2:"Limite du véhicule ligne Y",3:"Flèche",4:"Angles de vision"]
//Véhicule 3 position en X
vh3_X = -3.4; //[-22:0.1:22]
//Véhicule 3 position en Y
vh3_Y = -5.2; //[-22:0.1:22]
//Véhicule 3 angle
vh3_ang = -52;
//-- Vehicle 4 -------------------
//Type du véhicule 4 à afficher
vh4_type = 4; // [0:"Aucun",1:"Voiture rouge",2:"Voiture bleue",3:"Bus",4:"Cycliste"]
//Éléments accessoires du véhicule 4
vh4_acc = 0; // [0:"None",1:"Vehicle line limit X (for cars)",2:"Vehicle line limit Y (for cars)",3:"Arrow",4:"Views angles"]
//::vh4_acc = 0; // [0:"Sans",1:"Limite du véhicule ligne X",2:"Limite du véhicule ligne Y",3:"Flèche",4:"Angles de vision"]
//Véhicule 4 position en X
vh4_X = 4.4; //[-22:0.1:22]
//Véhicule 4 position en Y
vh4_Y = 8.8; //[-22:0.1:22]
//Véhicule 4 angle
vh4_ang = 155;
vh_type = [vh1_type,vh2_type,vh3_type,vh4_type];
vh_acc = [vh1_acc,vh2_acc,vh3_acc,vh4_acc];
vh_X = [vh1_X,vh2_X,vh3_X,vh4_X];
vh_Y = [vh1_Y,vh2_Y,vh3_Y,vh4_Y];
vh_ang = [vh1_ang,vh2_ang,vh3_ang,vh4_ang];
//==============================
/*[Texte Descriptif]*/
//Titre du projet
txt01 = "Titre du projet";
//Texte descriptif
txt02 = "description";
//_
txt03 = "";
//_
txt04 = "";
//_
txt05 = "";
//_
txt06 = "";
//_
txt07 = "";
//_
txt08 = "";
//_
txt09 = "";
//_
txt10 = "";
usertxt = [txt01,txt02,txt03,txt04,txt05,txt06,txt07,txt08,txt09,txt10];
//Concepteur
author="_";
//Date et révision
design="preliminary test";
//Licence
license="_";
designtxt = [str("Date, rev.: ",design), str("Author: ",author," License: ",license)];
//==============================
/*[Général]*/
//Coté de conduite à droite
right_drive = true;
//-------------
//Il y a des feux de circulation
traffic_light=true;
//------------
//Quelle route a priorité
road_priority = 1; //[0:"Aucune",1: "Route X", 2:"Route Y"]
//------------
//Priorité à la voie cyclable: sur les giratoires, une piste éloignée NON prioritaire peut offrir une meilleure sécurité
cycle_priority = true;
//move cycle way crossing from intersection - for roundabouts
_cycle_way_offset = 0; //[0:0.5:12]
cwo = _cycle_way_offset*cfu;
//-----------
//Carrefour en 'T' (pas de branche B en Y)
t_cross = false;
//Le feu est installé après le passage piéton (quand on le regarde)
light_after_crossing = true;
//Décalage du centre de rayon des coins de trottoir (augmente le rayon mais diminue l'espace pour les piétons)
_corner_offset = 0.2; //[0:0.1:3]
corner_offset = _corner_offset*cfu;
//Angle de raccordement de la deviation dans le carrefour, reduire donne une route plus directe
//Parking islands are in concrete (else they are painted)
parking_island_concrete = false;
//Longueur de la branche de déviation voiture (depuis le début de la route, pas du centre du carrefour)
_dev_length = 16;
dev_length = _dev_length*cfu;
//Longueur de la branche de déviation vélo (depuis le début de la route, pas du centre du carrefour)
_cydev_length = 10;
cydev_length = _cydev_length*cfu;
//Diamètre interne du rond-point, 0 si pas de rond-point
_round_int_diam=0; //[0:0.2:24]
round_int_diam=_round_int_diam*cfu;
//Partie diagonale des îlots de giratoire
_round_bias=6; //[0:0.2:15]
round_bias = _round_bias*cfu;
//Distance entre le rond-point et la piste cyclable (m)
_roundabout_space = 6; //[5:0.5:12]
roundabout_space = _roundabout_space*cfu;
//================================
/*[Nombre de voies principales]*/
//Route X branche A: nombre de voies à droite
XAr_nb_lanes = 2; // [0:1:4]
//Route X branche A, nombre de voies à gauche
XAl_nb_lanes = 1; // [0:4]
//Route X branche B, voies à droite
XBr_nb_lanes = 2; // [0:4]
//Route X branche B, voies à gauche
XBl_nb_lanes = 1; // [0:4]
//Route Y branche A: voies à droite
YAr_nb_lanes = 1; // [0:4]
//Route Y branche A, voies à gauche
YAl_nb_lanes = 1; // [0:4]
//Route Y branche B, voies à droite
YBr_nb_lanes = 1; // [0:4]
//Route Y branche B, voies à gauche
YBl_nb_lanes = 1; // [0:4]
//==============================
/*[Hidden]*/
//Road displayed length
_road_length = 46; //[40:2:100]
road_length = _road_length*cfu;
//echo(cfu=cfu, road_length =road_length);
//ground marking
//Length where you shall not park before a pedestrian passage (by law in France)
_park_protect = 5;
park_protect = _park_protect*cfu;
//Length of one car parking space
_park_space = 5; //[4.5:0.1:6]
park_space = _park_space*cfu;
//cycle path triangle distance from line
_cycle_triangle_dist = 0.15; //[0.15:0.05:0.4]
cycle_triangle_dist = _cycle_triangle_dist*cfu;
//cycle path triangle width
_cycle_triangle_wd = 0.4;
cycle_triangle_wd = _cycle_triangle_wd*cfu;
//cycle path triangle length
_cycle_triangle_lg = 0.6;
cycle_triangle_lg = _cycle_triangle_lg*cfu;
//cycle path triangle interval
_cycle_triangle_sp = 0.5;
cycle_triangle_sp = _cycle_triangle_sp*cfu;
//Misc dimensions
//hauteur du trottoir - depuis la route
_pavht=0.15;
pavht=_pavht*cfu;
//number of segment for pavement cylinder ends of 300mm diam. This is key to overall calculation time ??
pavseg=12;
//===============================
/*[Route X, parties communes]*/
//Right and left are from road when looking the crossing
//yet crossing is assumed to be straight and mirrorable
//Largeur de la route X (y compris les trottoirs)
XA_totwidth= 20; //[4:0.2:50]
//La branche B de la route X est en continuité de la branche A (même largeur, même trottoir, etc.)
XX = true; // [true]
//Trottoir de séparation médian
XA_central = 0; //[0:0.1:2]
//Largeur passage piéton (0: pas de passage)
XA_pedcross_wd = 2.5; // [0,2.5,3]
//Distance du passage piéton au bord de la route perpendiculaire
XA_pedcross_shift = 3; // [0.4:0.2:6]
//Angle de raccordement pour la déviation des pistes, le réduire diminue le décalage.
Xway_angle=45; //[15:5:45]
//Types de flèches au sol branche A (remplir tableau valeurs:"vers droite","tout droit","tout droit et droite")
XAr_lane_arrows = ["vers droite","tout droit","tout droit","tout droit"];
//["straight","right","straight right"]
//Types de flèches au sol branche en face (B) (remplir tableau valeurs:"vers droite","tout droit","tout droit et droite")
XBr_lane_arrows = ["vers droite","tout droit","tout droit","tout droit"];
//["straight","right","straight right"]
//permet une déviation automatique, branche A (pour optimiser l'espace intérieur)
XA_allow_dev=true;
//permet une déviation automatique, branche B (pour optimiser l'espace intérieur)
XB_allow_dev=true;
//==============================
/*[Route X coté droite, branche A]*/
//Largeur trottoir - au carrefour
XAr_pavement = 2; // [0.5:0.1:6]
//Largeur allée de coté (pour voitures ou vélos)
XAr_alley = 2; // [0:0.1:6]
//Is the alley a cycle path (-> change color)
//Allée entièrement réservée à la piste cyclable
XAr_cycle_path=true;
//La piste cyclable est en double sens
XAr_cycle_double = false;
//Largeur trottoir séparation entre allée et route, s'il y a une allée
XAr_alley_pav = 0.6; //[0.2:0.1:8]
//Largeur file de parking
XAr_park_lane=2; //[0,2,2.1,2.2]
//Largeur bande cyclable
XAr_cycle_lane = 0; //[0:0.1:2.5]
//Déviation de la piste cyclable (nécessite un trottoir de séparation large)
XAr_pavdev = 0; //[0:0.1:6]
//Voie bus (pas installé)
XAr_bus_lane = false;
//Voie bus (pas installé)
XBr_bus_lane = false;
/*/Buildings (decorative purpose only)
//Distance immeuble/trottoir (pas installé)
XAr_building = 0;
*/
//===============================
/*[Route X coté gauche, branche A]*/
//Largeur trottoir - au carrefour
XAl_pavement = 2; // [0.5:0.1:6]
//Largeur contre-allée
XAl_alley = 2; // [0:0.1:6]
//La contre-allée est une piste cyclable
XAl_cycle_path=true;
//La piste cyclable est à double sens
XAl_cycle_double = false;
//Largeur trottoir séparation entre allée et route, s'il y a une allée
XAl_alley_pav = 0.6; //[0.2:0.1:8]
//Largeur file de parking
XAl_park_lane = 0; //[0,2,2.1,2.2]
//Largeur bande cyclable
XAl_cycle_lane = 0; //[0:0.1:2.5]
//déviation de la piste cyclable (nécessite un trottoir de séparation large)
XAl_pavdev = 0; //[0:0.1:6]
//Voie de bus
XAl_bus_lane = false;
//Voie de bus sur la branche B
XBl_bus_lane = false;
/*/fr:Distance des bâtiments au bord de la route (décoratif uniquement)
//distance between building and road
XAl_building = 0;
*/
//===================================
/*[Route Y, parties communes]*/
//Largeur de la route Y (y compris les trottoirs)
YA_totwidth= 16; //[4:0.2:50]
//La branche B de la route Y est en continuité de la branche A (même largeur, même trottoir, etc.)
YY = true; // [true]
//Trottoir de séparation médian
YA_central = 0; //[0:0.1:2]
//Largeur passage piéton (0: pas de passage)
YA_pedcross_wd = 2.5; //[0,2.5,3]
//Distance du passage piéton au bord de la route perpendiculaire
YA_pedcross_shift = 3; // [0.4:0.2:6]
//Angle de raccordement pour la déviation des pistes, le réduire diminue le décalage.
Yway_angle=45; //[15:5:45]
//Types de flèches au sol branche A (remplir tableau valeurs:"vers droite","tout droit","tout droit et droite")
YAr_lane_arrows = ["","straight","straight","straight"];
///fr:Types de flèches au sol branche en face (B) (remplir tableau valeurs:"vers droite","tout droit","tout droit et droite")
//Road marking arrows facing branch (B)-(fill in array, values "right","straight","straight right")
YBr_lane_arrows = ["vers droite","tout droit","tout droit","tout droit"];
//permet une déviation automatique, branche A (pour optimiser l'espace intérieur)
YA_allow_dev=true;
//permet une déviation automatique, branche B (pour optimiser l'espace intérieur)
YB_allow_dev=true;
//===================================
/*[Route Y coté droite, branche A]*/
//Largeur trottoir - au carrefour
YAr_pavement = 2; // [0.5:0.1:6]
//Largeur contre-allée
YAr_alley = 0; // [0:0.1:6]
//La contre-allée est une piste cyclable
YAr_cycle_path=true;
//La piste cyclable est à double sens
YAr_cycle_double = false;
//Largeur trottoir séparant contre-allée et route
YAr_alley_pav = 0.7; // [0.2:0.1:8]
//Largeur file de parking
YAr_park_lane = 0; //[0,2,2.1,2.2]
//Largeur bande cyclable
YAr_cycle_lane = 2; //[0:0.1:2.5]
//déviation de la piste cyclable (nécessite un trottoir de séparation large)
YAr_pavdev = 0; //[0:0.1:6]
//Voie de bus
YAr_bus_lane = false;
//Voie de bus sur la branche B
YBr_bus_lane = false;
/*/fr:Distance des bâtiments au bord de la route (décoratif uniquement)
//distance between building and road
YAr_building = 0;
*/
//===================================
/*[Route Y coté gauche, branche A]*/
//Largeur trottoir - au carrefour
YAl_pavement = 2; // [0.5:0.1:6]
//Largeur contre-allée
YAl_alley = 0; // [0:0.1:6]
//La contre-allée est une piste cyclable
YAl_cycle_path=true;
//La piste cyclable est à double sens
YAl_cycle_double = false;
//Largeur trottoir séparation entre allée et route, s'il y a une allée
YAl_alley_pav = 0.7; //[0.2:0.1:8]
//Largeur file de parking
YAl_park_lane = 2; // [0,2,2.1,2.2]
//Largeur bande cyclable
YAl_cycle_lane = 2; //[0:0.1:2.5]
//déviation de la piste cyclable (nécessite un trottoir de séparation large)
YAl_pavdev = 0; //[0:0.1:6]
//Voie de bus
YAl_bus_lane = false;
//Voie de bus branche B
YBl_bus_lane = false;
/*/fr:Distance des bâtiments au bord de la route (décoratif uniquement)
//distance between building and road
YAl_building = 0;
*/
//====================================
/*[Marquage sol]*/
// en France, voir https://fr.wikipedia.org/wiki/Signalisation_routi%C3%A8re_horizontale_en_France
// u en ville = 5 cm
// u SUR les pistes cyclable = 3 cm
//Largeur ligne centrale
_road_cent_line = 150; // 3 u
//Largeur ligne séparation de voies (mm)
_road_sep_line = 100; // 2 u
//Largeur ligne voie bus (mm)
_bus_lane_line = 250; // 5 u
//Largeur ligne bande cyclables (mm)
_cycle_lane_line = 250; // 5 u
//Largeur ligne piste cyclable (dans carrefour) (mm)
//Cycle path side line thickness (in road crossing) (mm)
_cycle_cross_line = 250; // 5 u
//Largeur ligne séparation double sens piste cyclable (mm)
_cycle_cent_line = 90; //3u (u=30 for cycle)
//-- Stop line intervals if dashed ---
//Intervalle entre marques de ligne de stop piéton (mm)
_stop_line_lg = 1000;
//Espace entre marques de ligne de stop piéton (mm)
_stop_line_sp =200; //[0,200]
// according Vienna convention
//Largeur ligne de stop passage piéton (mm)
_stop_line_thk =500; //[500,600]
//Le passage piéton est de type 'Zèbre'
pedcross_zebra = true;
//Largeur lignes passages piéton en zèbre (mm)
_ped_zebra_line = 500;
//Largeur lignes latérale passages sans 'zèbre' (mm)
_pedcross_side_line = 200; // ??
//===================================
/*[Hidden]*/
road_cent_line= _road_cent_line*cfu_line;
road_sep_line = _road_sep_line*cfu_line;
bus_lane_line = _bus_lane_line*cfu_line;
cycle_lane_line = _cycle_lane_line*cfu_line;
cycle_cross_line= _cycle_cross_line*cfu_line;
cycle_cent_line = _cycle_cent_line*cfu_line;
stop_line_lg = _stop_line_lg*cfu_line;
stop_line_sp = _stop_line_sp*cfu_line;
stop_line_thk = _stop_line_thk*cfu_line;
ped_zebra_line = _ped_zebra_line*cfu_line;
pedcross_side_line=_pedcross_side_line*cfu_line;
//====================================
/*[Réglages fins]*/
//Augmentation du rayon de virage pour avoir un parcours plus circulaire. Réduit l'espace de stockage des véhicules motorisés
_rad_increase = 0; //[0:0.2:10]
rad_increase = _rad_increase*cfu;
//Réduction de la longueur droite pour gagner de l'espace de stockage des véhicules motorisés (valeur négative)
_straight_decrease = -1; //[-6:0.2:0]
straight_decrease = _straight_decrease*cfu;
//Rayon virage voiture (trottoir surbaissé)
_car_radius = 5; //[3.5:0.2:8]
car_radius = _car_radius*cfu;
//Rayon virage camions (trottoir pleine hauteur)
_truck_radius = 9; //[8:0.2:12]
truck_radius = _truck_radius*cfu;
//Augmentation de la largeur des pistes à l'intérieur du carrefour
_cycle_wd_extent_crossing = 0.25; //[0:0.05:0.80]
cycle_wd_extent_crossing = _cycle_wd_extent_crossing*cfu;
//Distance du trottoir au rayon de virage théorique (vers l'intérieur)
_radius_clearance = 0.25; //[0.1:0.1:0.8]
radius_clearance = _radius_clearance*cfu;
//---------------------------------
//Distance de la ligne de stop au passage piéton (m)
_stop_line = 4;
stop_line = _stop_line*cfu;
//Distance du poteau de feu au bord du trottoir (m)
_light_pole_dist = 0.3; //[0.3:0.05:1]
light_pole_dist = _light_pole_dist*cfu;
//Diamètre des feux principaux (en mm)
traffic_light_diam = 200; // [200,300]
/*[Hidden]*/
//What follow is legacy of former island design, but it have effect on bike light and protection pavement. To be deprecated or at least revised
//Correction position 1 ilot au coin C1
C1_island_pos1 = 0; //[-1.5:0.1:2.5]
//Correction position 2 ilot au coin C1
C1_island_pos2 = 0; //[0:0.1:2.5]
//-----------
//Correction position 1 ilot au coin C2
C2_island_pos1 = 0; //[-1.5:0.1:2.5]
//Correction position 2 ilot au coin C2
C2_island_pos2 = 0; //[0:0.1:2.5]
//------------------------------
//Correction position 1 ilot au coin C3
C3_island_pos1 = 0; //[-1.5:0.1:2.5]
//Correction position 2 ilot au coin C3
C3_island_pos2 = 0; //[0:0.1:2.5]
//---------------
//Correction position 1 ilot au coin C4
C4_island_pos1 = 0; //[-1.5:0.1:2.5]
//Correction position 2 ilot au coin C4
C4_island_pos2 = 0; //[0:0.1:2.5]
//Ajustement position feu piste double, coin C1
C1_dbl_light_adj = 0; //[0:0.1:2.5]
//Ajustement position feu piste double, coin C2
C2_dbl_light_adj = 0; //[0:0.1:2.5]
//Ajustement position feu piste double, coin C3
C3_dbl_light_adj = 0; //[0:0.1:2.5]
//Ajustement position feu piste double, coin C4
C4_dbl_light_adj = 0; //[0:0.1:2.5]
//====================================
/*[Couleurs]*/
//colors (web designation)
//color_road = "darkslategray";
//
//color_road = [0,0.06,0.012];
//Couleur de la route
color_road = "dimgray";
//Cycle lane or path color
//color_cycle = "firebrick";
//Couleur des voies cyclables
color_cycle = [0.78,0.1,0.1];
//Couleur bord de trottoir
color_pavement_border = "darkgray";
//Couleur trottoir
color_pavement = "lightgray";
/*/fr:Couleur bâtiments
//Buildings color
color_building = "cream";
//Couleur espace route/bâtiments
color_building_sep = "darkgreen";
*/
//=================================
//-- indexes --------------------
/*[Hidden]*/
vX = 0;
vY = 1;
vA = 0;
vB = 1;
vright = 0;
vleft = 1;
Wang = [[0,180],[90,270]];
//===================================
totwidth = [[XA_totwidth*cfu,(XB_totwidth?XB_totwidth:XA_totwidth)*cfu],[YA_totwidth*cfu,(YB_totwidth?YB_totwidth:YA_totwidth)*cfu]];
// width of perpendicular road
perpwidth = [[totwidth[1][0],totwidth[1][1]],[totwidth[0][0],totwidth[0][1]]];
//??? cross
//if (XX) {
XBr_pavement = XAl_pavement;
XBl_pavement = XAr_pavement;
//}
//if (YY) {
YBl_pavement = YAr_pavement;
YBr_pavement = YAl_pavement;
//}
Wpavement = [[[XAr_pavement*cfu,XBr_pavement*cfu],[XAl_pavement*cfu,XBl_pavement*cfu]],[[YAr_pavement*cfu,YBr_pavement*cfu],[YAl_pavement*cfu,YBl_pavement*cfu]]];
//echo (XAr_pavement=XAr_pavement, Wpavement=Wpavement);
// Deviation on pavement arrival
XBr_pavdev = XAl_pavdev;
XBl_pavdev = XAr_pavdev;
YBr_pavdev = YAl_pavdev;
YBl_pavdev = YAr_pavdev;
Wpavdev = [[[XAr_pavdev*cfu,XBr_pavdev*cfu],[XAl_pavdev*cfu,XBl_pavdev*cfu]],[[YAr_pavdev*cfu,YBr_pavdev*cfu],[YAl_pavdev*cfu,YBl_pavdev*cfu]]];
//???
XBr_alley = XAl_alley;
XBl_alley = XAr_alley;
YBr_alley = YAl_alley;
YBl_alley = YAr_alley;
Walley = [[[XAr_alley*cfu,XBr_alley*cfu],[XAl_alley*cfu,XBl_alley*cfu]],[[YAr_alley*cfu,YBr_alley*cfu],[YAl_alley*cfu,YBl_alley*cfu]]];
//???
XBr_alley_pav = XAl_alley_pav;
XBl_alley_pav = XAr_alley_pav;
YBr_alley_pav = YAl_alley_pav;
YBl_alley_pav = YAr_alley_pav;
Walley_pavement = [[[XAr_alley_pav*cfu,XBr_alley_pav*cfu],[XAl_alley_pav*cfu,XBl_alley_pav*cfu]],[[YAr_alley_pav*cfu,YBr_alley_pav*cfu],[YAl_alley_pav*cfu,YBl_alley_pav*cfu]]];
//echo(Wpavement =Wpavement, Walley=Walley);
//-----------------------------------
pvXrA = XAr_alley?XAr_alley_pav:0;
pvXlA = XAl_alley?XAl_alley_pav:0;
pvYrA = YAr_alley?YAr_alley_pav:0;
pvYlA = YAl_alley?YAl_alley_pav:0;
pvXrB = XBr_alley?XBr_alley_pav:0;
pvXlB = XBl_alley?XBl_alley_pav:0;
pvYrB = YBr_alley?YBr_alley_pav:0;
pvYlB = YBl_alley?YBl_alley_pav:0;
Wpav_alley = [[[pvXrA*cfu,pvXlA*cfu],[pvXrB*cfu,pvXlB*cfu]],[[pvYrA*cfu,pvYlA*cfu],[pvYrB*cfu,pvYlB*cfu]]];
//Real alley pavement width
real_alley_pav = Wpav_alley-Wpavdev;
//---------------------------------
//??? cross lanes
// use cfu if cycle path became a width ???
XBr_cycle_path = XAl_cycle_path;
XBl_cycle_path = XAr_cycle_path;
YBr_cycle_path = YAl_cycle_path;
YBl_cycle_path = YAr_cycle_path;
Wcycle_path = [[[XAr_cycle_path,XBr_cycle_path],[XAl_cycle_path,XBl_cycle_path]],[[YAr_cycle_path,YBr_cycle_path],[YAl_cycle_path,YBl_cycle_path]]];
//----------------------------------
//??? cross cycle_double
XBr_cycle_double = XAl_cycle_double;
XBl_cycle_double = XAr_cycle_double;
YBr_cycle_double = YAl_cycle_double;
YBl_cycle_double = YAr_cycle_double;
Wcycle_double = [[[XAr_cycle_double,XBr_cycle_double],[XAl_cycle_double,XBl_cycle_double]],[[YAr_cycle_double,YBr_cycle_double],[YAl_cycle_double,YBl_cycle_double]]];
//----------------------------------
//??? cross lanes
XBr_park_lane = XAl_park_lane;
XBl_park_lane = XAr_park_lane;
YBr_park_lane = YAl_park_lane;
YBl_park_lane = YAr_park_lane;
Wpark_lane = [[[XAr_park_lane*cfu,XAl_park_lane*cfu],[XBr_park_lane*cfu,XBl_park_lane*cfu]],[[YAr_park_lane*cfu,YAl_park_lane*cfu],[YBr_park_lane*cfu,YBl_park_lane*cfu]]];
//----------------------------------
//??? cross lanes
XBr_cycle_lane = XAl_cycle_lane;
XBl_cycle_lane = XAr_cycle_lane;
YBr_cycle_lane = YAl_cycle_lane;
YBl_cycle_lane = YAr_cycle_lane;
Wcycle_lane = [[[XAr_cycle_lane*cfu,XAl_cycle_lane*cfu],[XBr_cycle_lane*cfu,XBl_cycle_lane*cfu]],[[YAr_cycle_lane*cfu,YAl_cycle_lane*cfu],[YBr_cycle_lane*cfu,YBl_cycle_lane*cfu]]];
//echo(Wpark_lane=Wpark_lane, Wcycle_lane=Wcycle_lane);
//---------------------------------
//Next 8 pos vector is required for vector substraction, as totwidth is a 4 pos vector
Wtotwidth =[[[totwidth[vX][vA],totwidth[vX][vA]],[totwidth[vX][vB],totwidth[vX][vB]]] , [[totwidth[vY][vA],totwidth[vY][vA]],[totwidth[vY][vB],totwidth[vY][vB]]] ];
Wroad_start = Wtotwidth/2-Wpavement-Walley-Wpav_alley;
Wmain_start = Wroad_start-Wpark_lane-Wcycle_lane;
//echo(Wmain_start =Wmain_start,Wmain_start2 =Wmain_start2, Wcycle_lane=Wcycle_lane, Wpark_lane=Wpark_lane );
//echo(Wpav_alley=Wpav_alley ,Wroad_start=Wroad_start);
//-------------------------------
//??? check
//XBr_lane_arrows = XAr_lane_arrows;
//YBr_lane_arrows = YAr_lane_arrows;
Wlane_arrows = [[XAr_lane_arrows,XBr_lane_arrows],[YAr_lane_arrows,YBr_lane_arrows]];
//echo (Wlane_arrows);
//---------------------------------
Wpedcross_wd = [[XA_pedcross_wd*cfu,(XX?XA_pedcross_wd:XBr_pedcross_wd)*cfu],[YA_pedcross_wd*cfu,(YY?YA_pedcross_wd:YBr_pedcross_wd)*cfu]];
Wpedcross_shift = [[XA_pedcross_shift*cfu,(XX?XA_pedcross_shift:XBr_pedcross_shift)*cfu],[YA_pedcross_shift*cfu,(YY?YA_pedcross_shift:YBr_pedcross_shift)*cfu]];
//echo(Wpedcross_shift =Wpedcross_shift);
//???
XBr_central = XA_central;
YBr_central = YA_central;
Wcentral = [[XA_central*cfu,XBr_central*cfu],[YA_central*cfu,YBr_central*cfu]];
//-- calculated variables -----------
//determine road display
disp_road=Display_road&&!Projection&&$preview;
//Road priorities
Wpriority = [traffic_light || (road_priority==1)||(road_priority==0),traffic_light || (road_priority==2)||(road_priority==0)];
//pedestrian crossings and road limits
//start of the inside surface ??
Wpav_start = Wtotwidth/2-Wpavement;
Allow_dev = [[XA_allow_dev,XB_allow_dev],[YA_allow_dev,YB_allow_dev]];
//== Fonctions ======================
function way_ang (a,b) = round_int_diam?45:a==vX?Xway_angle:Yway_angle;
// algorithm can only increase radius if angle is 45°
//function rad_inc (a,b) = way_ang(a,b)==45?rad_increase:0;
function rad_inc (a,b) = rad_increase;
// width with central pavement
function Wusewidth (axis,branch) = Wmain_start[axis][branch][vleft]+Wmain_start[axis][branch][vright];
// width excluding central pavement
function Wintwidth (axis,branch) = Wusewidth (axis,branch)-Wcentral[axis][branch];
function Wlane_wd2 (axis,branch) = Wintwidth(axis,branch)/(Wnb_lanes[axis][branch][vleft]+Wnb_lanes[axis][branch][vright]);
// lanes are crossed
Wnb_lanes = [[[XAr_nb_lanes,XAl_nb_lanes],[XBr_nb_lanes,XBl_nb_lanes]],[[YAr_nb_lanes,YAl_nb_lanes],[YBr_nb_lanes,YBl_nb_lanes]]];
//echo(Wnb_lanes=Wnb_lanes);
////test = [["x","xB"],["y","yB"]];
//test = [[["xAr","xAl"],["xBr","xBl"]],[["yAr","yAl"],["yBr","yBl"]]];
//decho ("tab test; XAl, YAr,YBr,YBl",test[vX][vA][vleft],test[vY][vA][vright],test[vY][vB][vright],test[vY][vB][vleft]);
//===================================
//Space between the road and the bike way, to set light (on right) and estimate bike storage space (on left).
function spacerk (a,b,side) =
totwidth[a][b]/2-Wpavement[a][b][side]-Wcycle_wd(a,b,side)-Wmain_start[a][b][side]+(side?1:-1)*ispartdev(a,b,cr_border_r(a,b)); //*/
function Waxis_shift(a,b,side) =
Wmain_start[a][b][side]-Wlane_wd2(a,b)*Wnb_lanes[a][b][side]-Wcentral[a][b]/2;
function Waxis (a,b) =
(Wmain_start[a][b][vleft]-Wmain_start[a][b][vright])/2-isdev(a,b);
function Wcycle_pos2 (a,b,side) = Wcycle_lane[a][b][side]?(Wpark_lane[a][b][side])?Wroad_start[a][b][side]-Wpark_lane[a][b][side]:Wroad_start[a][b][side]:(Walley[a][b][side] && Wcycle_path[a][b][side])?totwidth[a][b]/2-Wpavement[a][b][side]:Wmain_start[a][b][side];
// if there is no cycle way, the cycling way is considered to be the beginning of the usable road
function Wcycle_wd (axis,branch, side) = Wcycle_lane[axis][branch][side]?Wcycle_lane[axis][branch][side]-cycle_lane_line:(Walley[axis][branch][side] && Wcycle_path[axis][branch][side])?Walley[axis][branch][side]:0;
//----------------------------------
// perpendicular branches
function paxis (axis) = axis?vX:vY;
function pbranch (axis,branch) = axis?(branch?vA:vB):(branch?vB:vA);
// previous branch (for border)
function prevbranch (axis,branch) = axis?(branch?vB:vA):(branch?vA:vB);
// Opposite branch
function oppbranch (branch) = branch?vA:vB;
//-----------------------------------
//* ??? replace below by functions ?
C1_radius= max(Wpavement[vX][vA][vright],Wpavement[vY][vA][vleft])+corner_offset;
corner_C1 =[totwidth[vY][0]/2+C1_radius-YAl_pavement*cfu,totwidth[vX][0]/2+C1_radius-Wpavement[vX][vA][vright]];
//---------
C2_radius= max(Wpavement[vX][vB][vleft],Wpavement[vY][vA][vright])+corner_offset;
corner_C2 =[-totwidth[vY][0]/2-C2_radius+YAr_pavement*cfu,totwidth[vX][0]/2+C2_radius-Wpavement[vX][vB][vleft]];
//----------
C3_radius= max(Wpavement[vX][vB][vright],Wpavement[vY][vB][vleft])+corner_offset;
corner_C3 =[-totwidth[vY][0]/2-C3_radius+YAr_pavement*cfu,-totwidth[vX][0]/2-C3_radius+XAl_pavement*cfu];
//----------
C4_radius= max(Wpavement[vX][vA][vleft],Wpavement[vY][vB][vright])+corner_offset;
corner_C4 =[totwidth[vY][0]/2+C4_radius-YAl_pavement*cfu,-totwidth[vX][0]/2-C4_radius+XAl_pavement*cfu];
//*/
radius1 = [[C1_radius,C3_radius],
[C2_radius,C4_radius]];
cy_radius1 = radius1;
corner1 = [[corner_C1,
[-corner_C3[0],-corner_C3[1]]],
[[corner_C2[1],-corner_C2[0]],
[-corner_C4[1],corner_C4[0]]]];
cy_corner1 = corner1;
function corner_pass(a,b) = radius1[a][b]-1.414*corner_offset;
corner_txt = str(
round100(corner_pass(vX,vA)),"/",
round100(corner_pass(vY,vA)),"/",
round100(corner_pass(vX,vB)),"/",
round100(corner_pass(vY,vB))," m"
);
function avg_radius (a,b) = (radius1[a][b]+radius1[paxis(a)][pbranch(a,b)])/2;
//bikepath middle radius
function bk_radius(a,b) = avg_radius(a,b)+rad_increase+Wcycle_wd(a,b,vright)/2+cycle_wd_extent_crossing/2;
//Bikepath radiuses for each branch XA to YB
radius_txt = str(
round100(bk_radius(vY,vB)),"/",
round100(bk_radius(vX,vA)),"/",
round100(bk_radius(vY,vA)),"/",
round100(bk_radius(vX,vB))," m"
);
// bikelight adjust ~review that ???
island_pos1 = [[C1_island_pos1*cfu,C3_island_pos1*cfu],
[C2_island_pos1*cfu,C4_island_pos1*cfu]];
island_pos2 = [[C1_island_pos2*cfu,C3_island_pos2*cfu],
[C2_island_pos2*cfu,C4_island_pos2*cfu]];
//bike light adjust on double cycle path
dbl_light_adj = [[C1_dbl_light_adj*cfu,C3_dbl_light_adj*cfu],
[C2_dbl_light_adj*cfu,C4_dbl_light_adj*cfu]];
// t_cross bend shift
tc_rshift = t_cross?Wpavement[vX][vA][vleft]:0;
// Geometry with reduced angle. start point = corner circle center
//The principle is that the corner center small radius is half the main corner radius, so there will be increased inlet radius then abrubt radius change. This is a bit like what is proposed by Alta Planning (USA). The lower the junction angle (less than 45°), the more abrupt the change. For 30°, for a corner radius of 1000, central radius 500, inlet radius will be 1594; That decrease the room for cars, but also decrease the cyclist swerve
t7 = 0.707107; //=cos/sin(45)
//y pos from corner angle at connection
function corn_ydec (r,an)= t7*0.5*r*(1+cos(45-an)+sin(45-an));
//x pos from corner angle at connection
function corn_xdec (r,an) = t7*0.5*r*(1+cos(45-an)-sin(45-an));
//radius of way when arrived
function rturn (r,an) = (r-corn_ydec(r,an))/(1-cos(an));
function dec_x (r,an) = -corn_xdec(r,an)+sin(an)*rturn(r,an);
function dec_y (r,an) = rturn(r,an)-r;
function xdiag (xdisp,r,an,wd,radinc=0)=
xdisp-corn_xdec(r,an)-(rturn(r,an)+wd+radinc)*sin(an);
// so Y diag = xdiag*tan(an);
//The following functions are all to define the external border Y coordinate of the bikeway in the crossing, as defined in the bikeway_cross(). This suppose all lanes end up contacting the main pavement corner, whatever alley, lanes, parking lane or else exists. This is the right lane continuing from the considered segment.
//-- External radius --
function cr_rad_ext (a,b) = rturn(avg_radius(a,b), way_ang(a,b))+wd_cross(a,b)+rad_inc(a,b);
//Distance available from corner center to road straight section
function avail_x (a,b) =
cy_corner1[a][b][0]
-(Wusewidth(paxis(a),pbranch(a,b))+straight_decrease)/2-Waxis(paxis(a),pbranch(a,b));
function avail_x2 (a,b) =
cy_corner1[paxis(a)][pbranch(a,b)][1]
-(Wusewidth(paxis(a),pbranch(a,b))+straight_decrease)/2+Waxis(paxis(a),pbranch(a,b));
function wd_cross(a,b) = Wcycle_wd(a,b,vright)+cycle_wd_extent_crossing;
function cr_border1 (a,b) = cy_corner1[a][b][1]
-corn_ydec(cy_radius1[a][b],way_ang(a,b))
+xdiag(avail_x(a,b),cy_radius1[a][b],way_ang(a,b), wd_cross(a,b),rad_inc(a,b))*tan(way_ang(a,b))
+(1-cos(way_ang(a,b)))*(rturn(cy_radius1[a][b],way_ang(a,b))+wd_cross(a,b)+rad_inc(a,b));
function cr_border2 (a,b) = cy_corner1[paxis(a)][pbranch(a,b)][0]
-corn_ydec(cy_radius1[paxis(a)][pbranch(a,b)],way_ang(a,b))
+xdiag(avail_x2(a,b),cy_radius1[paxis(a)][pbranch(a,b)],way_ang(a,b), wd_cross(a,b),rad_inc(a,b))*tan(way_ang(a,b))
+(1-cos(way_ang(a,b)))*(rturn(cy_radius1[paxis(a)][pbranch(a,b)],way_ang(a,b))+wd_cross(a,b)+rad_inc(a,b));
//Radiuses centers
// note that the centers in one direction and the other are not the same if angle is != 45°, there is three radiuses in one corner.
function crn_xr (a,b)=
corner1[a][b][0]+dec_x(radius1[a][b],way_ang(a,b));
function crn_xl (a,b)=
corner1[paxis(a)][prevbranch(a,b)][1]+dec_x(radius1[paxis(a)][prevbranch(a,b)],way_ang(a,b));
function crn_yr (a,b)=
corner1[a][b][1]+dec_y(radius1[a][b],way_ang(a,b));
function crn_yl (a,b)=
corner1[paxis(a)][prevbranch(a,b)][0]+dec_y(radius1[paxis(a)][prevbranch(a,b)],way_ang(a,b));
//-- Final border result ----------
function cr_border_r (a,b) = min(cr_border1(paxis(a),prevbranch(a,b)),cr_border2(paxis(a),prevbranch(a,b)));
//-- Calculate road radius of a roundabout --
function round_road_radius() =
min (
cr_border_r(vX,vA)-Wcycle_wd(vY,vB, vright),
cr_border_r(vY,vA)-Wcycle_wd(vX,vA, vright),
cr_border_r(vX,vB)-Wcycle_wd(vY,vA, vright),
cr_border_r(vY,vB)-Wcycle_wd(vX,vB, vright))-cycle_wd_extent_crossing;
d_roundline = 2*(round_road_radius()-roundabout_space);
//-- angle shape to cut islands --
module cutcorner (a, b, bottom=-100, ht=500, extent=true) {
ap = paxis(a);
bp = pbranch(a,b);
bprev = prevbranch(a,b);
bopp= oppbranch(b);
wayang = way_ang(a,b);
wayangp = way_ang(ap,bp);
total = totwidth[a][b];
border = min(cr_border1(a,b),cr_border2(a,b));
poslane1 = total/2-Wpavement[a][b][vright];
poslane2 = total/2-Wpavement[a][bopp][vleft];
way_tot = Wcycle_wd(a,b,vright)+cycle_wd_extent_crossing;
rad_ext = cr_rad_ext(a,b);
radius1u = rturn(radius1[a][b],wayang);
radius2u = rturn(radius1[ap][bp],wayang);
pos1xu= crn_xr(a,b);
pos2xu= crn_xl(a,bopp);
dyext = rad_ext*(1-cos(wayang));
dyint1 = radius1u*(1-cos(wayang));
dyint2 = radius2u*(1-cos(wayang));
lgseg1 = (border-poslane1-dyext-dyint1)/sin(wayang);
lgseg2 = (border-poslane2-dyext-dyint2)/sin(wayang);
lgstrseg = (pos1xu+pos2xu)-(rad_ext*2+radius1u+radius2u)*sin(wayang)-(lgseg1+lgseg2)*cos(wayang);
strshift = pos1xu-(rad_ext+radius1u)*sin(wayang)-lgseg1*cos(wayang)-lgstrseg/2;
totalprev = totwidth[ap][bprev];
borderprev = min(cr_border1(ap,bprev),cr_border2(ap,bprev));
poslane1prev = totalprev/2-Wpavement[ap][bprev][vright];
poslane2prev = totalprev/2-Wpavement[ap][oppbranch(bprev)][vleft];
way_totprev = Wcycle_wd(ap,bprev,vright)+cycle_wd_extent_crossing;
rad_extprev = cr_rad_ext(ap,bprev);
radius1uprev = rturn(radius1[ap][bprev],wayangp);
radius2uprev = rturn(radius1[a][b],wayangp);
pos1xuprev= crn_xr(ap,bprev);
pos2xuprev= crn_xl(ap,oppbranch(bprev));
dyextprev = rad_extprev*(1-cos(wayangp));
dyint1prev = radius1uprev*(1-cos(wayangp));
dyint2prev = radius2uprev*(1-cos(wayangp));