All Downloads are FREE. Search and download functionalities are using the official Maven repository.

one.empty3.growth.LSystem Maven / Gradle / Ivy

There is a newer version: 2024.5.10
Show newest version
/*
 * Copyright (c) 2023. Manuel Daniel Dahmen
 *
 *
 *    Copyright 2012-2023 Manuel Daniel Dahmen
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package one.empty3.growth;

import one.empty3.growth.graphics.Turtle2D;

import java.util.*;
import java.util.function.BiConsumer;

public class LSystem {
    private static final int MAX = 100;
    private int t = 0;
    private HashMap rules = new HashMap<>();
    private List symbols = new ArrayList<>();
    private HashSet constants = new HashSet<>();
    private Parameters parameters;
    private Map initialParameters = new HashMap<>();
    private boolean init = false;

    public LSystem() {
        initFirstSymbols();
    }

    /***
     * Call it just after constructor. // TODO Refactor
     */
    public void init() {
        if (!init)
            parameters = new Parameters(this);
        init = true;
    }

    public void addInitialParameter(Symbol symbol, Parameter parameter) {
        initialParameters.put(symbol, parameter);
    }


    public void addRule(SymbolSequence ss, SymbolSequence action) {
        rules.put(ss.parts(), action);
    }


    public void addInitialParam(Symbol symbol, Parameter parameter) throws Exception {
        initialParameters.put(symbol, parameter);

    }

    public Parameter getInitialParam(Symbol key) {
        return initialParameters.get(key);
    }

    public Parameter getParam(int t, String name) {

        return parameters.getParameter(t, name);
    }

    public HashMap getParams(int t) {
        return parameters.getParameters(t);
    }

    public HashMap getRules() {
        return rules;
    }

    private void initFirstSymbols() {
        t = 0;
        symbols = new ArrayList<>();

    }

    public SymbolSequence applyRules() throws NotWellFormattedSystem {
        /***
         * After this method call, the added sequence will
         * contains the current symbols of the system
         */
        if (getCurrentSymbols() == null) {
            throw new NotWellFormattedSystem("no cuurent symobols");
        }

        SymbolSequence data = getCurrentSymbols().parts();


        SymbolSequence rest = new SymbolSequence();


        for (int i = 0; i < data.size(); i++) {
            int ok = 0;

            for (Map.Entry entry : rules.entrySet()) {

                SymbolSequence symbols = entry.getKey().parts();
                SymbolSequence replacement = entry.getValue().parts();
                for (int j = 0; j < symbols.size() &&
                        i + j < data.size()
                        ; j++) {
                    if (data.get(i + j).equals(symbols.get(j))) {
                        ok++;
                    } else {
                        ok = 0;
                    }

                    if (ok == symbols.size() && ok > 0) {
                        rest.addAll(replacement);
                        i = i + j;
                        ok = 0;
                        break;
                    }
                }

            }
            if (ok == 0) {
                rest.add(data.get(i));

            }

        }
        t++;
        updateParams();

        symbols.add(rest);

        //Logger.getAnonymousLogger().log(Level.INFO, this);


        return rest;
    }

    public void addRule(String search, String replacement) {
        SymbolSequence[] rule = new SymbolSequence[2];
        rule[0] = new SymbolSequence();
        rule[1] = new SymbolSequence();

        byte[] searBytes = search.getBytes();

        byte[] replBytes = replacement.getBytes();
        for (byte searByte : searBytes) {
            rule[0].add(new Symbol((char) searByte));
        }

        for (byte replByte : replBytes) {
            rule[1].add(new Symbol((char) replByte));
        }

        addRule(rule[0], rule[1]);
    }

    public void addInitialSymbols(String is) {
        SymbolSequence start = new SymbolSequence();
        byte[] replBytes = is.getBytes();
        for (byte searByte : replBytes) {
            start.add(new Symbol((char) searByte));
        }
        setCurrentSymbols(start);
    }

    private void updateParams() {
        HashMap parameters = this.parameters.getParameters(t - 1);
        if (parameters != null)
            parameters.forEach(new BiConsumer() {
                @Override
                public void accept(String s, Parameter parameter) {
                    if (parameter != null) {
                        FunctionalParameter f;
                        f = new FunctionalParameter(
                                parameter.getName(),
                                parameter.eval(getT(), 0),
                                parameter.getFormula());
                        LSystem.this.parameters.addParameter(t, f);
                    }

                }
            });

    }


    public void sequenceGraphics(Turtle2D turtle2D) {

    }

    // TODO Vérifier cette méthode.
    public SymbolSequence getCurrentSymbols() {

        if (symbols.size() == 0) {
            SymbolSequence ss;
            symbols.add(ss = new SymbolSequence());
            initialParameters.forEach((symbol, parameter) -> ss.add(symbol));
            return symbols.get(0);
        }
        if (symbols.size() < t)
            return symbols.get(symbols.size() - 1);
        return symbols.get(t);
    }

    public void setCurrentSymbols(SymbolSequence ss) {
        symbols.add(ss);
    }

    public String toString() {
        final String[] s = {"LSystem(t==" + t + "\n"};
        for (int i = 0; i < symbols.size(); i++) {
            s[0] += "\nData\nSTEP" + i + "\n----\n";
            s[0] += symbols.get(i).parts().toString();
        }
        s[0] += "\nParameters values: \n";
        s[0] += parameters.toString();
        s[0] += "\nInitial parameters: \n";
        initialParameters.forEach(new BiConsumer() {
            @Override
            public void accept(Symbol symbol, Parameter parameter) {
                s[0] += "Symbol : " + symbol.getValue() + " Parameter : " + parameter.toString() + "\n";
            }
        });
        s[0] += "\nRules:\n";
        rules.forEach(new BiConsumer() {
            @Override
            public void accept(SymbolSequence symbolSequence, SymbolSequence action) {
                s[0] += "RULE\n" + symbolSequence.toString() + "\t==>>> " + action.toString() + "\n";
            }

        });
        return s[0];
    }

    public Map getInitialParameters() {
        HashMap params = new HashMap();
        initialParameters.forEach(new BiConsumer() {
            @Override
            public void accept(Symbol symbol, Parameter parameter) {
                params.put(symbol.getValue().toString(), parameter.getValue());
            }
        });
        return initialParameters;
    }

    int i = 0;

    public int getT() {
        return t;
    }

    public void addParameter(int t, Parameter functionalParameter) {
        functionalParameter.lSystem = this;
        if (t == 0) {
            addInitialParam(functionalParameter);
        }

        parameters.addParameter(t, functionalParameter);

    }

    public void addInitialParam(Parameter f) {
        f.lSystem = this;
        parameters.addParameter(0, f);
    }

    public void setCurrentSymbols(String a) {

        SymbolSequence start = new SymbolSequence();
        byte[] replBytes = a.getBytes();
        for (byte searByte : replBytes) {
            start.add(new Symbol((char) searByte));
        }
        setCurrentSymbols(start);
    }
}






© 2015 - 2024 Weber Informatics LLC | Privacy Policy