0

私は AP 化学クラスの分子ビューアに取り組んでいます。各要素に異なる色を割り当てています。たとえば、水素は白、炭素は黒、酸素は赤です。

レンダリングする新しい要素を呼び出すと、次のようになります。

newAtom(x, y, z, color);

その後、アトムがレンダリングされます。

100を超える要素があるため、さまざまな色があります。

これらすべての色に対して個別のクラスを作成する必要がありますか? 例えば:

public class AtomColors {

    // By atomic number
    public final static Color H = new Color(1, 1, 1, 1);
    public final static Color He = new Color(1, 0.5f, 1, 1);
    public final static Color Li = new Color(0.5f, 1, 1, 1);
    public final static Color Be = new Color(1, 1, 1, 0.5f);
}

標準的な方法やこれを行う方法があるかどうか、またどの方法が最も効率的かはわかりません。それが私の質問です。これを行うより良い方法はありますか?

4

6 に答える 6

7

ここではEnumが最適だと思います。列挙型は、言語が提供する構造体で関連する定数を表すために使用されます。

以下のように色を表現できます。

public enum ColorEnum {
    H(1, 1, 1, 1),
    He(1, 0.5f, 1, 1),
    Li(0.5f, 1, 1, 1),
    Be(1, 1, 1, 0.5f);

    private final float cyan;
    private final float magenta;
    private final float yellow;
    private final float black;

    EnumTest(float cyan, float megenta, float yellow, float black) {
        this.cyan = cyan;
        this.megenta = megenta;
        this.yellow = yellow;
        this.black = black;
    }

    public float getCyan() { return cyan; }
    public float getMegenta() { return megenta; }
    public float getYellow() { return yellow; }
    public float getBlack() { return black; }

    public Color getColor() {
            new Color(cyan, megenta, yellow, black);
    }
}

そして、このように使用します

newAtom(x, y, z, ColorEnum.He);

このトピックの詳細については、参照することをお勧めします

于 2013-09-23T02:38:11.280 に答える
1

あなたが持っているコードは大丈夫です。列挙型を使用しても問題ありません。ただし、ユーザーが色を再構成できるようにしたい場合、変数が最終的なものであるという事実により、それは困難になります。また、ユーザーが色を再構成できるようにする場合は、列挙型に色を格納しないでください。ベスト プラクティスとして、列挙型は不変でなければなりません。ユーザーが何らかの方法でデフォルトの配色スキームを上書きできるようにしたい場合、コードは次のようになります。

public enum Element
{
    Ac("Actinium", 89),
    Ag("Silver", 47),
    Al("Aluminum", 13); 
    // etcetera

    private final String americanEnglishName;
    private final int atomicNumber;

    private Element(String americanEnglishName, int atomicNumber)
    {
        this.americanEnglishName = americanEnglishName;
        this.atomicNumber = atomicNumber;
    }

    public String getAmericanEnglishName()
    {
        return americanEnglishName;
    }

    public int getAtomicNumber()
    {
        return atomicNumber;
    }
}

class ApplicationSettings
{
    private static final Map<Element, Color> DEFAULT_COLORING;
    static
    {
        EnumMap<Element, Color> colorMap = 
            new EnumMap<Element, Color>(Element.class);
        colorMap.put(Element.Ac, new Color(1, 2, 3));
        colorMap.put(Element.Ag, Color.green);
        colorMap.put(Element.Al, Color.blue);
        // etcetera

        DEFAULT_COLORING = Collections.unmodifiableMap(colorMap);
    }

    private Map<Element, Color> _userPreferredColors = DEFAULT_COLORING;

    public Map<Element, Color> getUserPreferredColors()
    {
        return _userPreferredColors;
    }

    public void setUserPreferredColors(Map<Element, Color> userPreferredColors)
    {
        _userPreferredColors = userPreferredColors;
    }
}

class Application
{
    private ApplicationSettings _settings;

    public Application(ApplicationSettings settings)
    {
        _settings = settings;
    }

    private void run()
    {
        for(Element element : Element.values())
        {
            Color color = _settings.getUserPreferredColors().get(element);
            System.out.println(element.getAmericanEnglishName() + "=" + color);
        }

    }

    public static void main(String[] args) 
    {
        ApplicationSettings settings = new ApplicationSettings();
        Application app = new Application(settings);
        app.run();
    }    
}
于 2013-09-23T03:17:38.433 に答える
0

標準的な方法やこれを行う方法があるかどうか、またどの方法が最も効率的かはわかりません。

「標準的な」方法はありませんが、あなたがやっている方法は問題ないはずです。

この方法で実行しても効率の問題はありません。(実際、どのように実行しても効率が問題になることはほとんどありません。パフォーマンスのボトルネックは、3D ジオメトリとレンダリング コードにある可能性があります。)

唯一の問題は、このアプローチが (多かれ少なかれ) データ構造の非正規化を強制することです。つまり、要素ではなく原子インスタンスに色を保存します。@MikeClarkの答えは、この点を明確に扱っています。(@JayPatelの答えもこれをやろうとしているようです...彼のモデリングにはいくつかの問題があります.いつから「ヘリウム」は色でしたか??)

これを行うより良い方法はありますか?

1 つの代替方法は、Map<String, Color>名前付き要素ごとに に色を設定することです。特に、新しい要素を追加したり、要素の色をその場で (つまり、コードを変更せずに) 変更したりしたい場合は特に、より柔軟になる可能性があります。

他にもありそうです。


私のアドバイスは、これを「考えすぎ」ないことです。自分にとって自然と思われる方法で実装するだけで、「最適ではない」データ構造設計の決定の結果として、コードがぎこちなく/繰り返し/乱雑になり始めた場合は、決定を再検討してください。

于 2013-09-23T02:44:46.233 に答える
0

各色には、分子ビューアに渡す必要がある番号が関連付けられていると想定しています。

要素名 (または色名)キーとしてHashMapを作成でき、色番号になります。

于 2013-09-23T02:39:52.077 に答える
0

コンパイル時に既知の定数のリスト (周期表の要素など) がある場合はいつでも、列挙型を使用する適切なタイミングです。列挙型はインスタンス制御されており、すぐに使用できるタイプ セーフです。また、必要に応じて、列挙型メソッドや定数固有のメソッドを追加する柔軟性があります。

さらに、Enum 定数のコレクションの操作を簡素化する最適化されたコレクション クラスが既に用意されています。EnumSet (たとえば、色の組み合わせを表すことができる列挙型のセット用)、および特定の列挙型定数にマップされたデータのコレクションを操作するための EnumMap です。

于 2013-09-23T03:20:38.570 に答える
0

あなたのデザインでは、色は原子の特性のようです。オブジェクト指向設計の観点から、各AtomクラスにColorその色を格納するプロパティを持たせます。このnewAtomメソッドは、Atom描画する位置とオブジェクトを取得し、 の color プロパティにアクセスして、Atom描画する色を決定します。

原子の一意の色を簡単に保証したい場合は、陽子の数を使用して色を生成します。たとえば、緑と青の値を一定に保ち、陽子の数に応じて異なる赤の値 (0 ~ 255) を生成します。 )。

于 2013-09-23T02:42:44.883 に答える