@@ -35,6 +35,7 @@ import {
3535} from "./renderer-formule.js?v=app" ;
3636
3737const WASM_URL = "mandelbrot.wasm?v=app" ;
38+ const MODES_COULEUR_TRAITS_LSYSTEME = new Set ( [ "uniforme" , "progression" , "profondeur" , "orientation" ] ) ;
3839
3940// ============================================================
4041// ÉTAT DE L'APPLICATION
@@ -64,6 +65,7 @@ const params = {
6465 coloringMode : "standard" ,
6566 palettePhase : 0.0 ,
6667 paletteContours : false ,
68+ lsystemLineColor : "progression" ,
6769 deepZoomAutoIterations : false ,
6870 deepZoomQuality : "standard" ,
6971 studio3dMaterial : "lumineux" ,
@@ -229,6 +231,8 @@ const customPaletteStops = document.getElementById("custom-palette-stops");
229231const addPaletteStopButton = document . getElementById ( "btn-add-palette-stop" ) ;
230232const paletteBackgroundInput = document . getElementById ( "palette-background" ) ;
231233const paletteInteriorInput = document . getElementById ( "palette-interior" ) ;
234+ const lsystemLineColorGroup = document . getElementById ( "lsystem-line-color-group" ) ;
235+ const lsystemLineColorSelect = document . getElementById ( "lsystem-line-color-select" ) ;
232236const btnReset = document . getElementById ( "btn-reset" ) ;
233237const btnPanUp = document . getElementById ( "btn-pan-up" ) ;
234238const btnPanLeft = document . getElementById ( "btn-pan-left" ) ;
@@ -830,15 +834,23 @@ function definirVisibiliteEditeurPalette(forceOuverture) {
830834}
831835
832836function synchroniserControlePalette ( ) {
837+ if ( ! MODES_COULEUR_TRAITS_LSYSTEME . has ( params . lsystemLineColor ) ) params . lsystemLineColor = "progression" ;
833838 paletteSelect . value = params . palette ;
834839 if ( paletteSelectCompact ) paletteSelectCompact . value = params . palette ;
840+ if ( lsystemLineColorSelect ) lsystemLineColorSelect . value = params . lsystemLineColor || "progression" ;
841+ mettreAJourVisibiliteCouleurTraits ( ) ;
835842 paletteBackgroundInput . value = normaliserHexCouleur ( params . paletteBackground , "#020008" ) ;
836843 paletteInteriorInput . value = normaliserHexCouleur ( params . paletteInterior , "#fff5b4" ) ;
837844 params . paletteStops = normaliserStopsPalette ( params . paletteStops , PALETTES . aurora . stops . map ( ( stop ) => rgbVersHex ( stop ) ) ) ;
838845 definirVisibiliteEditeurPalette ( ) ;
839846 mettreAJourResumeControles ( ) ;
840847}
841848
849+ function mettreAJourVisibiliteCouleurTraits ( ) {
850+ const afficher = Boolean ( params . lsystemProposalActive ) ;
851+ if ( lsystemLineColorGroup ) lsystemLineColorGroup . classList . toggle ( "hidden" , ! afficher ) ;
852+ }
853+
842854function definirVisibiliteOptionsSpecifiques ( { labels = [ ] } = { } ) {
843855 const afficher = labels . length > 0 ;
844856 if ( controlsSpecific ) controlsSpecific . classList . toggle ( "hidden" , ! afficher ) ;
@@ -1025,6 +1037,7 @@ function capturerVueCourante() {
10251037 coloringMode : params . coloringMode ,
10261038 palettePhase : params . palettePhase ,
10271039 paletteContours : params . paletteContours ,
1040+ lsystemLineColor : params . lsystemLineColor ,
10281041 deepZoomAutoIterations : params . deepZoomAutoIterations ,
10291042 deepZoomQuality : params . deepZoomQuality ,
10301043 studio3dMaterial : params . studio3dMaterial ,
@@ -1090,6 +1103,7 @@ function clonerParamsExport(source = params) {
10901103 coloringMode : source . coloringMode ?? params . coloringMode ,
10911104 palettePhase : source . palettePhase ?? params . palettePhase ,
10921105 paletteContours : source . paletteContours ?? params . paletteContours ,
1106+ lsystemLineColor : source . lsystemLineColor ?? params . lsystemLineColor ,
10931107 deepZoomAutoIterations : source . deepZoomAutoIterations ?? params . deepZoomAutoIterations ,
10941108 deepZoomQuality : source . deepZoomQuality ?? params . deepZoomQuality ,
10951109 studio3dMaterial : source . studio3dMaterial ?? params . studio3dMaterial ,
@@ -1767,6 +1781,7 @@ function appliquerPropositionLSysteme(config) {
17671781 view . centerY = 0.0 ;
17681782 view . pixelSize = 2.4 / Math . max ( canvas . width , 1 ) ;
17691783 view . rotation = 0.0 ;
1784+ mettreAJourVisibiliteCouleurTraits ( ) ;
17701785 mettreAJourOptionsSpecifiques ( ) ;
17711786 explorationModes ?. syncFromParams ( ) ;
17721787 render ( ) ;
@@ -1776,6 +1791,7 @@ function appliquerPropositionLSysteme(config) {
17761791
17771792function effacerPropositionLSysteme ( ) {
17781793 params . lsystemProposalActive = false ;
1794+ mettreAJourVisibiliteCouleurTraits ( ) ;
17791795 mettreAJourOptionsSpecifiques ( ) ;
17801796 explorationModes ?. syncFromParams ( ) ;
17811797 render ( ) ;
@@ -1988,6 +2004,13 @@ function creerTraceurMonde(ctxCible, w, h, vueCible) {
19882004 lineTo ( x , y ) {
19892005 ctxCible . lineTo ( ( x - cx0 ) / vueCible . pixelSize , ( y - cy0 ) / vueCible . pixelSize ) ;
19902006 } ,
2007+ segmentColorie ( x0 , y0 , x1 , y1 , couleur ) {
2008+ ctxCible . beginPath ( ) ;
2009+ ctxCible . strokeStyle = "rgb(" + couleur [ 0 ] + ", " + couleur [ 1 ] + ", " + couleur [ 2 ] + ")" ;
2010+ ctxCible . moveTo ( ( x0 - cx0 ) / vueCible . pixelSize , ( y0 - cy0 ) / vueCible . pixelSize ) ;
2011+ ctxCible . lineTo ( ( x1 - cx0 ) / vueCible . pixelSize , ( y1 - cy0 ) / vueCible . pixelSize ) ;
2012+ ctxCible . stroke ( ) ;
2013+ } ,
19912014 } ;
19922015}
19932016
@@ -2098,7 +2121,21 @@ function dessinerCommandeLineaireMonde(traceur, commands, x, y, angle, segment,
20982121 }
20992122}
21002123
2101- function dessinerPropositionLSystemeMonde ( traceur , renduParams ) {
2124+ function couleurSegmentLSysteme ( segment , index , total , renduParams ) {
2125+ const mode = renduParams . lsystemLineColor || "progression" ;
2126+ if ( mode === "uniforme" ) {
2127+ return getColor ( Math . min ( renduParams . maxIter * 0.6 , renduParams . maxIter - 1 ) , renduParams . maxIter , renduParams ) ;
2128+ }
2129+ let t = total <= 1 ? 0 : index / ( total - 1 ) ;
2130+ if ( mode === "profondeur" ) {
2131+ t = Math . min ( 0.999 , ( segment . profondeur || 0 ) / 7 ) ;
2132+ } else if ( mode === "orientation" ) {
2133+ t = ( ( segment . angle % ( Math . PI * 2 ) ) + Math . PI * 2 ) / ( Math . PI * 2 ) ;
2134+ }
2135+ return getColorFromRatio ( t , renduParams ) ;
2136+ }
2137+
2138+ function dessinerPropositionLSystemeMonde ( traceur , renduParams , couleurParSegment = false ) {
21022139 const { points } = pointsPropositionLSysteme ( {
21032140 axiom : renduParams . lsystemAxiom ,
21042141 rules : renduParams . lsystemRules ,
@@ -2118,11 +2155,28 @@ function dessinerPropositionLSystemeMonde(traceur, renduParams) {
21182155 const scale = 1.82 / span ;
21192156 const centerX = ( minX + maxX ) * 0.5 ;
21202157 const centerY = ( minY + maxY ) * 0.5 ;
2121- points . forEach ( ( point , index ) => {
2122- const x = ( point . x - centerX ) * scale ;
2123- const y = - ( point . y - centerY ) * scale ;
2124- if ( index === 0 || point . move ) traceur . moveTo ( x , y ) ;
2125- else traceur . lineTo ( x , y ) ;
2158+ const pointsMonde = points . map ( ( point ) => ( {
2159+ x : ( point . x - centerX ) * scale ,
2160+ y : - ( point . y - centerY ) * scale ,
2161+ move : point . move ,
2162+ profondeur : point . profondeur || 0 ,
2163+ angle : point . angle || 0 ,
2164+ } ) ) ;
2165+ const segments = [ ] ;
2166+ pointsMonde . forEach ( ( point , index ) => {
2167+ const precedent = pointsMonde [ index - 1 ] ;
2168+ if ( index === 0 || point . move || ! precedent ) return ;
2169+ segments . push ( { x0 : precedent . x , y0 : precedent . y , x1 : point . x , y1 : point . y , profondeur : point . profondeur , angle : point . angle } ) ;
2170+ } ) ;
2171+ if ( couleurParSegment && typeof traceur . segmentColorie === "function" ) {
2172+ segments . forEach ( ( segment , index ) => {
2173+ traceur . segmentColorie ( segment . x0 , segment . y0 , segment . x1 , segment . y1 , couleurSegmentLSysteme ( segment , index , segments . length , renduParams ) ) ;
2174+ } ) ;
2175+ return ;
2176+ }
2177+ pointsMonde . forEach ( ( point , index ) => {
2178+ if ( index === 0 || point . move ) traceur . moveTo ( point . x , point . y ) ;
2179+ else traceur . lineTo ( point . x , point . y ) ;
21262180 } ) ;
21272181}
21282182
@@ -2355,9 +2409,12 @@ function dessinerFractaleLineaire(ctxCible, w, h, vueCible, renduParams, skipBac
23552409 ctxCible . lineWidth = Math . max ( 1 , Math . min ( 2 , w / 800 ) ) ;
23562410 ctxCible . beginPath ( ) ;
23572411 const traceur = creerTraceurMonde ( ctxCible , w , h , vueCible ) ;
2412+ let renduColorie = false ;
23582413
23592414 if ( renduParams . lsystemProposalActive ) {
2360- dessinerPropositionLSystemeMonde ( traceur , renduParams ) ;
2415+ const contexteCanvas = typeof CanvasRenderingContext2D !== "undefined" && ctxCible instanceof CanvasRenderingContext2D ;
2416+ renduColorie = contexteCanvas && renduParams . lsystemLineColor !== "uniforme" ;
2417+ dessinerPropositionLSystemeMonde ( traceur , renduParams , renduColorie ) ;
23612418 } else if ( renduParams . fractal === "koch" ) {
23622419 const n = Math . max ( 0 , Math . min ( 6 , Math . floor ( ( renduParams . maxIter - 64 ) / 128 ) ) ) ;
23632420 const commands = kochGenerate ( n ) ;
@@ -2406,7 +2463,7 @@ function dessinerFractaleLineaire(ctxCible, w, h, vueCible, renduParams, skipBac
24062463 dessinerBranche ( 0.0 , 1.35 , Math . PI / 2 , 0.42 , profondeur ) ;
24072464 }
24082465
2409- ctxCible . stroke ( ) ;
2466+ if ( ! renduColorie ) ctxCible . stroke ( ) ;
24102467}
24112468
24122469async function remplirFractalePonctuelle ( w , h , data , cx0 , cy0 , ps , renduParams ) {
@@ -3461,6 +3518,14 @@ if (paletteSelectCompact) {
34613518 } ) ;
34623519}
34633520
3521+ if ( lsystemLineColorSelect ) {
3522+ lsystemLineColorSelect . addEventListener ( "change" , ( ) => {
3523+ params . lsystemLineColor = lsystemLineColorSelect . value ;
3524+ render ( ) ;
3525+ mettreAJourHash ( view , params ) ;
3526+ } ) ;
3527+ }
3528+
34643529toggleCustomPaletteButton . classList . add ( "icon-btn" ) ;
34653530toggleCustomPaletteButton . addEventListener ( "click" , ( ) => {
34663531 if ( params . palette !== "personnalisee" ) return ;
@@ -3860,6 +3925,7 @@ async function appliquerSignet(signet) {
38603925 params . coloringMode = signet . coloringMode ?? params . coloringMode ;
38613926 params . palettePhase = signet . palettePhase ?? params . palettePhase ;
38623927 params . paletteContours = signet . paletteContours ?? params . paletteContours ;
3928+ params . lsystemLineColor = signet . lsystemLineColor ?? params . lsystemLineColor ;
38633929 params . deepZoomAutoIterations = signet . deepZoomAutoIterations ?? params . deepZoomAutoIterations ;
38643930 params . deepZoomQuality = signet . deepZoomQuality ?? params . deepZoomQuality ;
38653931 params . studio3dMaterial = signet . studio3dMaterial ?? params . studio3dMaterial ;
@@ -4024,6 +4090,7 @@ async function init() {
40244090 params . coloringMode = etatHash . coloringMode ?? params . coloringMode ;
40254091 params . palettePhase = etatHash . palettePhase ?? params . palettePhase ;
40264092 params . paletteContours = etatHash . paletteContours ?? params . paletteContours ;
4093+ params . lsystemLineColor = etatHash . lsystemLineColor ?? params . lsystemLineColor ;
40274094 params . deepZoomAutoIterations = etatHash . deepZoomAutoIterations ?? params . deepZoomAutoIterations ;
40284095 params . deepZoomQuality = etatHash . deepZoomQuality ?? params . deepZoomQuality ;
40294096 params . studio3dMaterial = etatHash . studio3dMaterial ?? params . studio3dMaterial ;
0 commit comments