Bug Fix
This commit is contained in:
57
Concepts/Bond2D.cs
Normal file
57
Concepts/Bond2D.cs
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Godot;
|
||||||
|
using VirtualChemDemo.Scenes;
|
||||||
|
using VirtualChemistry.Chemistry.Bonds.Implements;
|
||||||
|
|
||||||
|
namespace VirtualChemDemo.Concepts;
|
||||||
|
|
||||||
|
public abstract partial class Bond2D : Line2D
|
||||||
|
{
|
||||||
|
public BaseBond BondFrom { get; set; }
|
||||||
|
public BaseBond BondTo { get; set; }
|
||||||
|
public Atom AtomFrom { get; set; }
|
||||||
|
public Atom AtomTo { get; set; }
|
||||||
|
protected Label BondTypeA { get; set; }
|
||||||
|
protected Label BondTypeB { get; set; }
|
||||||
|
/*public string TypeA { get; set; }
|
||||||
|
public string TypeB { get; set; }*/
|
||||||
|
public int Index { get; set; } = 999;
|
||||||
|
public int Multi { get; set; } = -1;
|
||||||
|
|
||||||
|
public override void _Ready()
|
||||||
|
{
|
||||||
|
BondTypeA = GetNode<Label>("BondTypeA");
|
||||||
|
BondTypeB = GetNode<Label>("BondTypeB");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Reindex()
|
||||||
|
{
|
||||||
|
HashSet<Bond2D> bonds = new();
|
||||||
|
foreach (Bond2D bond in GlobalScene.CompoundConstructor.BondMap[AtomFrom])
|
||||||
|
{
|
||||||
|
if (
|
||||||
|
(bond.AtomTo == AtomTo && bond.AtomFrom == AtomFrom) ||
|
||||||
|
(bond.AtomFrom == AtomTo && bond.AtomTo == AtomFrom)
|
||||||
|
)
|
||||||
|
bonds.Add(bond);
|
||||||
|
}
|
||||||
|
|
||||||
|
int idx = 1;
|
||||||
|
foreach (Bond2D bond in bonds.OrderBy(x => x.Index))
|
||||||
|
{
|
||||||
|
if (bond.Index != idx)
|
||||||
|
bond.Index = idx;
|
||||||
|
idx++;
|
||||||
|
bond.Multi = bonds.Count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void BondUpdate();
|
||||||
|
public static Bond2D Resolve(BaseBond b1, BaseBond b2)
|
||||||
|
{
|
||||||
|
if (b1.Atom == b2.Atom)
|
||||||
|
return ResourceLoader.Load<PackedScene>("res://Scenes/SelfBond.tscn").Instantiate<SelfBond>();
|
||||||
|
return ResourceLoader.Load<PackedScene>("res://Scenes/SingleBond.tscn").Instantiate<SingleBond>();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,10 +2,11 @@ public static class GlobalScene
|
|||||||
{
|
{
|
||||||
public static MainScene MainScene { get; set; }
|
public static MainScene MainScene { get; set; }
|
||||||
public static CompoundConstructor CompoundConstructor { get; set; }
|
public static CompoundConstructor CompoundConstructor { get; set; }
|
||||||
public static VirtualChemDemo Demo { get; set; }
|
public static VirtualChemistryDemo Demo { get; set; }
|
||||||
public static MainControlPanel MainControlPanel { get; set; }
|
public static MainControlPanel MainControlPanel { get; set; }
|
||||||
public static Flask Flask { get; set; }
|
public static Flask Flask { get; set; }
|
||||||
|
|
||||||
public static StringLoader StringLoader { get; set; }
|
public static StringLoader StringLoader { get; set; }
|
||||||
|
public static bool ElasticContainer { get; set; } = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,34 +0,0 @@
|
|||||||
using Godot;
|
|
||||||
|
|
||||||
public partial class Bond : Line2D
|
|
||||||
{
|
|
||||||
public Atom AtomFrom { get; set; }
|
|
||||||
public Atom AtomTo { get; set; }
|
|
||||||
private Label BondTypeA { get; set; }
|
|
||||||
private Label BondTypeB { get; set; }
|
|
||||||
public string TypeA { get; set; }
|
|
||||||
public string TypeB { get; set; }
|
|
||||||
|
|
||||||
public override void _Ready()
|
|
||||||
{
|
|
||||||
BondTypeA = GetNode<Label>("BondTypeA");
|
|
||||||
BondTypeB = GetNode<Label>("BondTypeB");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void BondUpdate()
|
|
||||||
{
|
|
||||||
Vector2 v1 = AtomFrom.Position + new Vector2(32, 32);
|
|
||||||
Vector2 v2 = AtomTo.Position + new Vector2(32, 32);
|
|
||||||
Vector2 m = (v1 + v2) / 2;
|
|
||||||
Points = new[] { v1, m, v2 };
|
|
||||||
BondTypeA.Position = m - new Vector2(10, 10);
|
|
||||||
BondTypeB.Position = m + new Vector2(10, 10);
|
|
||||||
BondTypeA.Text = TypeA;
|
|
||||||
BondTypeB.Text = TypeB;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Called every frame. 'delta' is the elapsed time since the previous frame.
|
|
||||||
public override void _Process(double delta)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
[gd_scene load_steps=2 format=3 uid="uid://ngc8dex7loqv"]
|
|
||||||
|
|
||||||
[ext_resource type="Script" path="res://Scenes/Bond.cs" id="1_rpgkt"]
|
|
||||||
|
|
||||||
[node name="Bond" type="Line2D"]
|
|
||||||
default_color = Color(1, 0.0392157, 1, 0.690196)
|
|
||||||
joint_mode = 2
|
|
||||||
begin_cap_mode = 2
|
|
||||||
end_cap_mode = 2
|
|
||||||
script = ExtResource("1_rpgkt")
|
|
||||||
|
|
||||||
[node name="BondTypeA" type="Label" parent="."]
|
|
||||||
offset_right = 40.0
|
|
||||||
offset_bottom = 23.0
|
|
||||||
|
|
||||||
[node name="BondTypeB" type="Label" parent="."]
|
|
||||||
offset_right = 40.0
|
|
||||||
offset_bottom = 23.0
|
|
||||||
@@ -65,6 +65,8 @@ public partial class Bottle : MenuButton, IChemicalContainer
|
|||||||
GlobalScene.MainScene.SwitchToConstructor();
|
GlobalScene.MainScene.SwitchToConstructor();
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
|
if (GlobalScene.Flask.Content.Layers.Count == 0)
|
||||||
|
return;
|
||||||
Content = GlobalScene.Flask.Content;
|
Content = GlobalScene.Flask.Content;
|
||||||
Content.Container = this;
|
Content.Container = this;
|
||||||
GlobalScene.Flask.Content = HeterogeneousMixture.Null;
|
GlobalScene.Flask.Content = HeterogeneousMixture.Null;
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Godot;
|
using Godot;
|
||||||
|
using VirtualChemDemo;
|
||||||
|
using VirtualChemDemo.Concepts;
|
||||||
using VirtualChemistry.Chemistry.Atoms.Implements;
|
using VirtualChemistry.Chemistry.Atoms.Implements;
|
||||||
using VirtualChemistry.Chemistry.Atoms.Resolver;
|
using VirtualChemistry.Chemistry.Atoms.Resolver;
|
||||||
using VirtualChemistry.Chemistry.Bonds.Implements;
|
using VirtualChemistry.Chemistry.Bonds.Implements;
|
||||||
@@ -15,7 +18,7 @@ public partial class CompoundConstructor : Panel
|
|||||||
public HashSet<Atom> Atoms { get; set; } = new();
|
public HashSet<Atom> Atoms { get; set; } = new();
|
||||||
public BaseBond ConnectPending { get; set; } = BaseBond.Null;
|
public BaseBond ConnectPending { get; set; } = BaseBond.Null;
|
||||||
public Atom PendingAtom { get; set; }
|
public Atom PendingAtom { get; set; }
|
||||||
public Dictionary<Atom, HashSet<Bond>> BondMap { get; set; } = new();
|
public Dictionary<Atom, HashSet<Bond2D>> BondMap { get; set; } = new();
|
||||||
|
|
||||||
// Called when the node enters the scene tree for the first time.
|
// Called when the node enters the scene tree for the first time.
|
||||||
public override void _Ready()
|
public override void _Ready()
|
||||||
@@ -25,9 +28,65 @@ public partial class CompoundConstructor : Panel
|
|||||||
HomogeneousMixture = HeterogeneousMixture.AddLayer();
|
HomogeneousMixture = HeterogeneousMixture.AddLayer();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called every frame. 'delta' is the elapsed time since the previous frame.
|
private static class AtomPositionFixMemory
|
||||||
|
{
|
||||||
|
public static Atom[] SavedAtoms { get; set; } = null;
|
||||||
|
private static int I { get; set; }
|
||||||
|
private static int J { get; set; }
|
||||||
|
public static int Max => SavedAtoms.Length;
|
||||||
|
|
||||||
|
public static void Reset()
|
||||||
|
{
|
||||||
|
SavedAtoms = null;
|
||||||
|
I = 0;
|
||||||
|
J = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void OneStep()
|
||||||
|
{
|
||||||
|
if (J >= Max)
|
||||||
|
{
|
||||||
|
J = 0;
|
||||||
|
I++;
|
||||||
|
}
|
||||||
|
if (I >= Max)
|
||||||
|
{
|
||||||
|
Reset();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (I == J)
|
||||||
|
{
|
||||||
|
J++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Atom a1 = SavedAtoms[I];
|
||||||
|
Atom a2 = SavedAtoms[J];
|
||||||
|
|
||||||
|
if ((a1.Position - a2.Position).Length() < 64)
|
||||||
|
{
|
||||||
|
Vector2 pd = a1.Position - a2.Position;
|
||||||
|
if (pd == Vector2.Zero)
|
||||||
|
pd = new Vector2(J % 3 - 2, I % 3 - 1);
|
||||||
|
a1.Position += pd;
|
||||||
|
a2.Position -= pd;
|
||||||
|
if (GlobalScene.CompoundConstructor.BondMap.TryGetValue(a1, out var bonds1))
|
||||||
|
foreach (Bond2D b1 in bonds1)
|
||||||
|
b1.BondUpdate();
|
||||||
|
if(GlobalScene.CompoundConstructor.BondMap.TryGetValue(a2, out var bonds2))
|
||||||
|
foreach (Bond2D b2 in bonds2)
|
||||||
|
b2.BondUpdate();
|
||||||
|
}
|
||||||
|
J++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public override void _Process(double delta)
|
public override void _Process(double delta)
|
||||||
{
|
{
|
||||||
|
if (AtomPositionFixMemory.SavedAtoms == null)
|
||||||
|
AtomPositionFixMemory.SavedAtoms = Atoms.ToArray();
|
||||||
|
AtomPositionFixMemory.OneStep();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool _CanDropData(Vector2 atPosition, Variant data)
|
public override bool _CanDropData(Vector2 atPosition, Variant data)
|
||||||
@@ -40,7 +99,7 @@ public partial class CompoundConstructor : Panel
|
|||||||
Atom a = data.As<Atom>();
|
Atom a = data.As<Atom>();
|
||||||
a.Position = atPosition;
|
a.Position = atPosition;
|
||||||
if(BondMap.ContainsKey(a))
|
if(BondMap.ContainsKey(a))
|
||||||
foreach (Bond b in BondMap[a])
|
foreach (Bond2D b in BondMap[a])
|
||||||
b.BondUpdate();
|
b.BondUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,6 +115,7 @@ public partial class CompoundConstructor : Panel
|
|||||||
at.Position = new(500, 500);
|
at.Position = new(500, 500);
|
||||||
HomogeneousMixture.AddCompound(c, true, true);
|
HomogeneousMixture.AddCompound(c, true, true);
|
||||||
Atoms.Add(at);
|
Atoms.Add(at);
|
||||||
|
AtomPositionFixMemory.Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveAtomOf(Atom atom)
|
public void RemoveAtomOf(Atom atom)
|
||||||
@@ -63,11 +123,11 @@ public partial class CompoundConstructor : Panel
|
|||||||
foreach (BaseBond b in atom.BaseAtom.ConnectedBonds)
|
foreach (BaseBond b in atom.BaseAtom.ConnectedBonds)
|
||||||
b.Disconnect();
|
b.Disconnect();
|
||||||
|
|
||||||
Bond[] toRemove = Array.Empty<Bond>();
|
Bond2D[] toRemove = Array.Empty<Bond2D>();
|
||||||
if (BondMap.TryGetValue(atom, out HashSet<Bond> value))
|
if (BondMap.TryGetValue(atom, out HashSet<Bond2D> value))
|
||||||
toRemove = value.ToArray();
|
toRemove = value.ToArray();
|
||||||
|
|
||||||
foreach (Bond b in toRemove)
|
foreach (Bond2D b in toRemove)
|
||||||
{
|
{
|
||||||
BondMap[b.AtomFrom].Remove(b);
|
BondMap[b.AtomFrom].Remove(b);
|
||||||
BondMap[b.AtomTo].Remove(b);
|
BondMap[b.AtomTo].Remove(b);
|
||||||
@@ -79,29 +139,32 @@ public partial class CompoundConstructor : Panel
|
|||||||
atom.BaseAtom.Compound = Compound.Null;
|
atom.BaseAtom.Compound = Compound.Null;
|
||||||
RemoveChild(atom);
|
RemoveChild(atom);
|
||||||
Atoms.Remove(atom);
|
Atoms.Remove(atom);
|
||||||
|
AtomPositionFixMemory.Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ConnectAtoms(Atom a, BaseBond b)
|
public void ConnectAtoms(Atom a, BaseBond b)
|
||||||
{
|
{
|
||||||
b.Connect(ConnectPending);
|
b.Connect(ConnectPending);
|
||||||
Bond bond = ResourceLoader.Load<PackedScene>("res://Scenes/Bond.tscn").Instantiate<Bond>();
|
Bond2D bond = Bond2D.Resolve(b, ConnectPending);
|
||||||
bond.AtomFrom = PendingAtom;
|
bond.AtomFrom = PendingAtom;
|
||||||
bond.AtomTo = a;
|
bond.AtomTo = a;
|
||||||
bond.TypeA = ConnectPending.BondType;
|
bond.BondFrom = ConnectPending;
|
||||||
bond.TypeB = b.BondType;
|
bond.BondTo = b;
|
||||||
|
|
||||||
if (!BondMap.ContainsKey(a))
|
if (!BondMap.ContainsKey(a))
|
||||||
BondMap[a] = new HashSet<Bond>();
|
BondMap[a] = new HashSet<Bond2D>();
|
||||||
BondMap[a].Add(bond);
|
BondMap[a].Add(bond);
|
||||||
if (!BondMap.ContainsKey(PendingAtom!))
|
if (!BondMap.ContainsKey(PendingAtom!))
|
||||||
BondMap[PendingAtom] = new HashSet<Bond>();
|
BondMap[PendingAtom] = new HashSet<Bond2D>();
|
||||||
BondMap[PendingAtom].Add(bond);
|
BondMap[PendingAtom].Add(bond);
|
||||||
ConnectPending = BaseBond.Null;
|
ConnectPending = BaseBond.Null;
|
||||||
a.AtomActions.BuildMenu();
|
a.AtomActions.BuildMenu();
|
||||||
PendingAtom.AtomActions.BuildMenu();
|
PendingAtom.AtomActions.BuildMenu();
|
||||||
PendingAtom = null;
|
PendingAtom = null;
|
||||||
AddChild(bond);
|
AddChild(bond);
|
||||||
bond.BondUpdate();
|
foreach (Bond2D bd in BondMap[a])
|
||||||
|
bd.BondUpdate();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Back()
|
private void Back()
|
||||||
@@ -111,11 +174,14 @@ public partial class CompoundConstructor : Panel
|
|||||||
|
|
||||||
private void Build()
|
private void Build()
|
||||||
{
|
{
|
||||||
|
if(HomogeneousMixture.Compounds.Count==0)
|
||||||
|
return;
|
||||||
HeterogeneousMixture.Container = GlobalScene.Demo.SelectedBottle;
|
HeterogeneousMixture.Container = GlobalScene.Demo.SelectedBottle;
|
||||||
GlobalScene.Demo.SelectedBottle.Content = HeterogeneousMixture;
|
GlobalScene.Demo.SelectedBottle.Content = HeterogeneousMixture;
|
||||||
GlobalScene.Demo.SelectedBottle.BuildMenu();
|
GlobalScene.Demo.SelectedBottle.BuildMenu();
|
||||||
|
|
||||||
Clear();
|
Clear();
|
||||||
|
Back();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Clear(bool save = true)
|
private void Clear(bool save = true)
|
||||||
@@ -127,13 +193,13 @@ public partial class CompoundConstructor : Panel
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
HashSet<Bond> removedBonds = new();
|
HashSet<Bond2D> removedBonds = new();
|
||||||
foreach (Atom atom in Atoms)
|
foreach (Atom atom in Atoms)
|
||||||
{
|
{
|
||||||
RemoveChild(atom);
|
RemoveChild(atom);
|
||||||
if (!BondMap.ContainsKey(atom))
|
if (!BondMap.ContainsKey(atom))
|
||||||
continue;
|
continue;
|
||||||
foreach (Bond bond in BondMap[atom])
|
foreach (Bond2D bond in BondMap[atom])
|
||||||
{
|
{
|
||||||
if (!removedBonds.Contains(bond))
|
if (!removedBonds.Contains(bond))
|
||||||
RemoveChild(bond);
|
RemoveChild(bond);
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ public partial class Flask : TextureRect, IChemicalContainer
|
|||||||
{
|
{
|
||||||
public double ContainerVolume { get; set; } = 0.5;
|
public double ContainerVolume { get; set; } = 0.5;
|
||||||
private TextureRect InnerLayer { get; set; }
|
private TextureRect InnerLayer { get; set; }
|
||||||
public double Volume() => ContainerVolume;
|
public double Volume() => GlobalScene.ElasticContainer ? Content.Volume : ContainerVolume;
|
||||||
|
|
||||||
public HeterogeneousMixture Content { get; set; }
|
public HeterogeneousMixture Content { get; set; }
|
||||||
public double EnvironmentPressure { get; set; }
|
public double EnvironmentPressure { get; set; }
|
||||||
@@ -55,6 +55,11 @@ public partial class Flask : TextureRect, IChemicalContainer
|
|||||||
InnerLayer = GetNode<TextureRect>("InnerLayer");
|
InnerLayer = GetNode<TextureRect>("InnerLayer");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void ShowAll()
|
||||||
|
{
|
||||||
|
GlobalScene.MainControlPanel.BuildAllTree();
|
||||||
|
}
|
||||||
|
|
||||||
// Called every frame. 'delta' is the elapsed time since the previous frame.
|
// Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||||
public override void _Process(double delta)
|
public override void _Process(double delta)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -21,3 +21,13 @@ offset_right = 40.0
|
|||||||
offset_bottom = 40.0
|
offset_bottom = 40.0
|
||||||
mouse_filter = 2
|
mouse_filter = 2
|
||||||
texture = ExtResource("1_b34pm")
|
texture = ExtResource("1_b34pm")
|
||||||
|
|
||||||
|
[node name="ShowAll" type="Button" parent="."]
|
||||||
|
layout_mode = 0
|
||||||
|
offset_left = 185.0
|
||||||
|
offset_top = 107.0
|
||||||
|
offset_right = 229.0
|
||||||
|
offset_bottom = 138.0
|
||||||
|
text = "Show All"
|
||||||
|
|
||||||
|
[connection signal="pressed" from="ShowAll" to="." method="ShowAll"]
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ public partial class FlaskContent : ColorRect
|
|||||||
|
|
||||||
public HomogeneousMixture Mixture { get; set; } = HomogeneousMixture.Null;
|
public HomogeneousMixture Mixture { get; set; } = HomogeneousMixture.Null;
|
||||||
private const double ContainerHeight = 512d;
|
private const double ContainerHeight = 512d;
|
||||||
public double ContainerVolume => Mixture.HeterogeneousMixture.Container.Volume();
|
private double ContainerVolume => Mixture.HeterogeneousMixture.Container.Volume();
|
||||||
public double Volume => Mixture.Volume;
|
public double Volume => Mixture.Volume;
|
||||||
private TextureButton Mask { get; set; }
|
private TextureButton Mask { get; set; }
|
||||||
|
|
||||||
@@ -31,22 +31,21 @@ public partial class FlaskContent : ColorRect
|
|||||||
double height = (Volume / ContainerVolume) * ContainerHeight;
|
double height = (Volume / ContainerVolume) * ContainerHeight;
|
||||||
Position = new Vector2(Position.X, 512-(float)(StartFrom + height));
|
Position = new Vector2(Position.X, 512-(float)(StartFrom + height));
|
||||||
Size = new Vector2(Size.X, (float)height);
|
Size = new Vector2(Size.X, (float)height);
|
||||||
//Mask.Size = Size;
|
|
||||||
Color = Color.Color8(
|
Color = Color.Color8(
|
||||||
Mixture.ColorRed,
|
Mixture.ColorRed,
|
||||||
Mixture.ColorGreen,
|
Mixture.ColorGreen,
|
||||||
Mixture.ColorGreen,
|
Mixture.ColorGreen,
|
||||||
Mixture.ColorTransparent
|
Mixture.ColorTransparent
|
||||||
);
|
);
|
||||||
/*
|
|
||||||
Animation a = AP.GetAnimation("HeightChange");
|
/*Animation a = AP.GetAnimation("HeightChange");
|
||||||
a.TrackSetKeyValue(0, 0, Size);
|
a.TrackSetKeyValue(0, 0, Size);
|
||||||
a.TrackSetKeyValue(0, 1, new Vector2(Size.X, (float)height));
|
a.TrackSetKeyValue(0, 1, new Vector2(Size.X, (float)height));
|
||||||
AP.Play("HeightChange");
|
AP.Play("HeightChange");
|
||||||
AP.Play("PositionChange");
|
AP.Play("PositionChange");
|
||||||
a = AP.GetAnimation("PositionChange");
|
a = AP.GetAnimation("PositionChange");
|
||||||
a.TrackSetKeyValue(0,0,Position);
|
a.TrackSetKeyValue(0,0,Position);
|
||||||
a.TrackSetKeyValue(0,1, new Vector2(Position.X, -(float)StartFrom));
|
a.TrackSetKeyValue(0,1, new Vector2(Position.X, 512-(float)(StartFrom + height)));
|
||||||
Color = Color.Color8(Mixture.ColorRed, Mixture.ColorGreen, Mixture.ColorGreen, Mixture.ColorTransparent);
|
Color = Color.Color8(Mixture.ColorRed, Mixture.ColorGreen, Mixture.ColorGreen, Mixture.ColorTransparent);
|
||||||
AP.Play();*/
|
AP.Play();*/
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ public partial class MainControlPanel : HBoxContainer
|
|||||||
private Label FreeVolume { get; set; }
|
private Label FreeVolume { get; set; }
|
||||||
private Label Stiffness { get; set; }
|
private Label Stiffness { get; set; }
|
||||||
private Tree Compounds { get; set; }
|
private Tree Compounds { get; set; }
|
||||||
// Called when the node enters the scene tree for the first time.
|
|
||||||
public override void _Ready()
|
public override void _Ready()
|
||||||
{
|
{
|
||||||
EnvTemperature = GetNode<HSlider>("V1/EnvTemperature");
|
EnvTemperature = GetNode<HSlider>("V1/EnvTemperature");
|
||||||
@@ -53,13 +53,43 @@ public partial class MainControlPanel : HBoxContainer
|
|||||||
BuildTree();
|
BuildTree();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void BuildAllTree()
|
||||||
|
{
|
||||||
|
Compounds.Clear();
|
||||||
|
TreeItem root = Compounds.CreateItem();
|
||||||
|
root.SetText(0, "Mixtures: ");
|
||||||
|
int i = 1;
|
||||||
|
foreach (HomogeneousMixture h in GlobalScene.Flask.Content.LayerOrder)
|
||||||
|
{
|
||||||
|
TreeItem sRoot = Compounds.CreateItem(root);
|
||||||
|
sRoot.SetText(0,$"Mixture{i} Amt{h.Amount}");
|
||||||
|
foreach (var group in h.Compounds.GroupBy(x => x.Expression))
|
||||||
|
{
|
||||||
|
TreeItem t = Compounds.CreateItem(root);
|
||||||
|
t.SetText(0, group.Key);
|
||||||
|
t.SetSelectable(0, false);
|
||||||
|
int j = 1;
|
||||||
|
foreach (Compound c in group)
|
||||||
|
{
|
||||||
|
TreeItem x = Compounds.CreateItem(t);
|
||||||
|
x.SetText(0, $"{j}th isomer");
|
||||||
|
x.SetMeta("isoExp", c.IsoRepresentation);
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void BuildTree()
|
private void BuildTree()
|
||||||
{
|
{
|
||||||
Compounds.Clear();
|
Compounds.Clear();
|
||||||
var groups = SelectedMixture.Compounds.GroupBy(x => x.Expression);
|
var groups = SelectedMixture.Compounds.GroupBy(x => x.Expression);
|
||||||
|
TreeItem root = Compounds.CreateItem(null);
|
||||||
|
root.SetText(0, "Compounds: ");
|
||||||
foreach (var group in groups)
|
foreach (var group in groups)
|
||||||
{
|
{
|
||||||
TreeItem t = Compounds.CreateItem();
|
TreeItem t = Compounds.CreateItem(root);
|
||||||
t.SetText(0, group.Key);
|
t.SetText(0, group.Key);
|
||||||
t.SetSelectable(0, false);
|
t.SetSelectable(0, false);
|
||||||
int i = 1;
|
int i = 1;
|
||||||
@@ -108,4 +138,14 @@ public partial class MainControlPanel : HBoxContainer
|
|||||||
GlobalScene.Flask.ContainerVolume = vol;
|
GlobalScene.Flask.ContainerVolume = vol;
|
||||||
GlobalScene.Flask.Update();
|
GlobalScene.Flask.Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void SetElasticContainer(bool on)
|
||||||
|
{
|
||||||
|
GlobalScene.ElasticContainer = on;
|
||||||
|
if (on)
|
||||||
|
ContainerVolume.Editable = false;
|
||||||
|
else
|
||||||
|
ContainerVolume.Editable = true;
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,6 +44,12 @@ min_value = 0.2
|
|||||||
max_value = 20.0
|
max_value = 20.0
|
||||||
step = 0.2
|
step = 0.2
|
||||||
value = 1.0
|
value = 1.0
|
||||||
|
ticks_on_borders = true
|
||||||
|
|
||||||
|
[node name="ElasticContainer" type="CheckBox" parent="V1"]
|
||||||
|
layout_mode = 2
|
||||||
|
tooltip_text = "Volume of container always equal to the volume of content"
|
||||||
|
text = "Elastic Container"
|
||||||
|
|
||||||
[node name="VSeparator" type="VSeparator" parent="."]
|
[node name="VSeparator" type="VSeparator" parent="."]
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
@@ -138,12 +144,8 @@ layout_mode = 2
|
|||||||
[node name="V3" type="VBoxContainer" parent="."]
|
[node name="V3" type="VBoxContainer" parent="."]
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
|
|
||||||
[node name="Label" type="Label" parent="V3"]
|
|
||||||
layout_mode = 2
|
|
||||||
text = "Compounents"
|
|
||||||
|
|
||||||
[node name="Compounds" type="Tree" parent="V3"]
|
[node name="Compounds" type="Tree" parent="V3"]
|
||||||
custom_minimum_size = Vector2(150, 200)
|
custom_minimum_size = Vector2(250, 200)
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
|
|
||||||
[node name="VSeparator4" type="VSeparator" parent="."]
|
[node name="VSeparator4" type="VSeparator" parent="."]
|
||||||
@@ -154,4 +156,5 @@ layout_mode = 2
|
|||||||
[connection signal="pressed" from="V1/RemoveBottom" to="." method="RemoveBottom"]
|
[connection signal="pressed" from="V1/RemoveBottom" to="." method="RemoveBottom"]
|
||||||
[connection signal="value_changed" from="V1/EnvTemperature" to="." method="SetTemperature"]
|
[connection signal="value_changed" from="V1/EnvTemperature" to="." method="SetTemperature"]
|
||||||
[connection signal="value_changed" from="V1/ContainerVolume" to="." method="SetVolume"]
|
[connection signal="value_changed" from="V1/ContainerVolume" to="." method="SetVolume"]
|
||||||
|
[connection signal="toggled" from="V1/ElasticContainer" to="." method="SetElasticContainer"]
|
||||||
[connection signal="item_selected" from="V3/Compounds" to="." method="IsomerSelectedHandler"]
|
[connection signal="item_selected" from="V3/Compounds" to="." method="IsomerSelectedHandler"]
|
||||||
|
|||||||
@@ -4,12 +4,12 @@ using System;
|
|||||||
public partial class MainScene : Node2D
|
public partial class MainScene : Node2D
|
||||||
{
|
{
|
||||||
public Node CurrentScene { get; set; }
|
public Node CurrentScene { get; set; }
|
||||||
public VirtualChemDemo Demo { get; set; }
|
public VirtualChemistryDemo Demo { get; set; }
|
||||||
|
|
||||||
public override void _Ready()
|
public override void _Ready()
|
||||||
{
|
{
|
||||||
GlobalScene.MainScene = this;
|
GlobalScene.MainScene = this;
|
||||||
Demo = GetNode<VirtualChemDemo>("Demo");
|
Demo = GetNode<VirtualChemistryDemo>("Demo");
|
||||||
CurrentScene = Demo;
|
CurrentScene = Demo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
[gd_scene load_steps=3 format=3 uid="uid://cgdqxc2mx6w8l"]
|
[gd_scene load_steps=3 format=3 uid="uid://cgdqxc2mx6w8l"]
|
||||||
|
|
||||||
[ext_resource type="Script" path="res://Scenes/MainScene.cs" id="1_uwony"]
|
[ext_resource type="Script" path="res://Scenes/MainScene.cs" id="1_uwony"]
|
||||||
[ext_resource type="PackedScene" uid="uid://br78rurjakp3a" path="res://Scenes/VirtualChemDemo.tscn" id="2_vpu75"]
|
[ext_resource type="PackedScene" uid="uid://br78rurjakp3a" path="res://Scenes/VirtualChemistryDemo.tscn" id="2_vpu75"]
|
||||||
|
|
||||||
[node name="MainScene" type="Node2D"]
|
[node name="MainScene" type="Node2D"]
|
||||||
script = ExtResource("1_uwony")
|
script = ExtResource("1_uwony")
|
||||||
|
|||||||
9
Scenes/MultiBond.cs
Normal file
9
Scenes/MultiBond.cs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
using VirtualChemDemo.Concepts;
|
||||||
|
|
||||||
|
public partial class MultiBond : Bond2D
|
||||||
|
{
|
||||||
|
public override void BondUpdate()
|
||||||
|
{
|
||||||
|
throw new System.NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
25
Scenes/SelfBond.cs
Normal file
25
Scenes/SelfBond.cs
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using Godot;
|
||||||
|
using VirtualChemDemo.Concepts;
|
||||||
|
|
||||||
|
namespace VirtualChemDemo.Scenes;
|
||||||
|
|
||||||
|
public partial class SelfBond : Bond2D
|
||||||
|
{
|
||||||
|
public override void BondUpdate()
|
||||||
|
{
|
||||||
|
Reindex();
|
||||||
|
List<Vector2> points = new();
|
||||||
|
Vector2 pcenter = new(30, 0);
|
||||||
|
pcenter = pcenter.Rotated((float)Index * Mathf.Pi * 2f / (float)Multi);
|
||||||
|
Vector2 center = AtomFrom.Position + new Vector2(32, 32) + pcenter;
|
||||||
|
Vector2 d = AtomFrom.Position + new Vector2(32, 32) - center;
|
||||||
|
for (int i = 0; i <= 24; i++)
|
||||||
|
points.Add(center + d.Rotated(i*Mathf.Pi*2/24));
|
||||||
|
BondTypeA.Position = points[12] + new Vector2(-20, 0);
|
||||||
|
BondTypeB.Position = points[12] + new Vector2(20, 0);
|
||||||
|
Points = points.ToArray();
|
||||||
|
BondTypeA.Text = BondFrom.BondType;
|
||||||
|
BondTypeB.Text = BondTo.BondType;
|
||||||
|
}
|
||||||
|
}
|
||||||
97
Scenes/SingleBond.cs
Executable file
97
Scenes/SingleBond.cs
Executable file
@@ -0,0 +1,97 @@
|
|||||||
|
using System;
|
||||||
|
using Godot;
|
||||||
|
using VirtualChemDemo.Concepts;
|
||||||
|
|
||||||
|
public partial class SingleBond : Bond2D
|
||||||
|
{
|
||||||
|
private static int BIndex(int index, int multi)
|
||||||
|
{
|
||||||
|
if (multi == 1)
|
||||||
|
return 0;
|
||||||
|
if (multi % 2 == 1)
|
||||||
|
{
|
||||||
|
int center = multi / 2 + 1;
|
||||||
|
return center - index;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (multi % 2 == 0)
|
||||||
|
{
|
||||||
|
double center = multi / 2 + 0.5;
|
||||||
|
return (int)(center > index ? Math.Ceiling(center - index) : Math.Floor(center - index));
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
private void MakeCurve(float curveRate=20f, int cDir = 1)
|
||||||
|
{
|
||||||
|
Vector2 Start = AtomFrom.Position + new Vector2(32, 32);;
|
||||||
|
Vector2 End = AtomTo.Position + new Vector2(32, 32);;
|
||||||
|
Vector2[] xs = new Vector2[17];
|
||||||
|
int[] x2 = new[] { 4, 12 };
|
||||||
|
int[] x3 = new[] { 2, 6, 10, 14};
|
||||||
|
int[] x4 = new[] { 1, 3, 5, 7, 9, 11, 13, 15 };
|
||||||
|
Vector2 vd = End - Start;
|
||||||
|
Vector2 nor = vd.Rotated(Mathf.Pi / 2 * cDir);
|
||||||
|
Vector2 center = vd / 2 + 4f * nor / curveRate;
|
||||||
|
xs[0] = Start;
|
||||||
|
xs[16] = End;
|
||||||
|
xs[8] = center + xs[0];
|
||||||
|
foreach (int i in x2)
|
||||||
|
{
|
||||||
|
Vector2 v = xs[i + 4] - xs[i - 4];
|
||||||
|
Vector2 n = v.Rotated(Mathf.Pi / 2 * cDir);
|
||||||
|
Vector2 w = v / 2 + 2f * n / curveRate;
|
||||||
|
xs[i] = w + xs[i - 4];
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (int i in x3)
|
||||||
|
{
|
||||||
|
Vector2 v = xs[i + 2] - xs[i - 2];
|
||||||
|
Vector2 n = v.Rotated(Mathf.Pi / 2 * cDir);
|
||||||
|
Vector2 w = v / 2 + n / curveRate;
|
||||||
|
xs[i] = w + xs[i - 2];
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (int i in x4)
|
||||||
|
{
|
||||||
|
Vector2 v = xs[i + 1] - xs[i - 1];
|
||||||
|
Vector2 n = v.Rotated(Mathf.Pi / 2 * cDir);
|
||||||
|
Vector2 w = v / 2 + n / curveRate;
|
||||||
|
xs[i] = w + xs[i - 1];
|
||||||
|
}
|
||||||
|
BondTypeA.Position = xs[10];
|
||||||
|
BondTypeB.Position = xs[6];
|
||||||
|
Points = xs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void BondUpdate()
|
||||||
|
{
|
||||||
|
Reindex();
|
||||||
|
int bindex = BIndex(Index, Multi);
|
||||||
|
if (bindex == 0)
|
||||||
|
{
|
||||||
|
Vector2 v1 = AtomFrom.Position + new Vector2(32, 32);
|
||||||
|
Vector2 v2 = AtomTo.Position + new Vector2(32, 32);
|
||||||
|
Vector2 m = (v1 + v2) / 2;
|
||||||
|
Points = new[] { v1, m, v2 };
|
||||||
|
BondTypeA.Position = m - new Vector2(10, 10);
|
||||||
|
BondTypeB.Position = m + new Vector2(10, 10);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float curveRate = 25 - Math.Abs(bindex)*5;
|
||||||
|
int cDir = bindex > 0 ? 1 : -1;
|
||||||
|
MakeCurve(curveRate, cDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
BondTypeA.Text = BondFrom.BondType;
|
||||||
|
BondTypeB.Text = BondTo.BondType;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||||
|
public override void _Process(double delta)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,10 +4,7 @@ using VirtualChemistry.Chemistry.Mixtures.Resolver;
|
|||||||
|
|
||||||
public partial class StringLoader : Window
|
public partial class StringLoader : Window
|
||||||
{
|
{
|
||||||
|
|
||||||
public TextEdit Input { get; set; }
|
public TextEdit Input { get; set; }
|
||||||
|
|
||||||
// Called when the node enters the scene tree for the first time.
|
|
||||||
public override void _Ready()
|
public override void _Ready()
|
||||||
{
|
{
|
||||||
Input = GetNode<TextEdit>("V1/Input");
|
Input = GetNode<TextEdit>("V1/Input");
|
||||||
@@ -21,6 +18,7 @@ public partial class StringLoader : Window
|
|||||||
HeterogeneousMixture mixture = HeterogeneousMixtureResolver.Resolve(expression);
|
HeterogeneousMixture mixture = HeterogeneousMixtureResolver.Resolve(expression);
|
||||||
GlobalScene.Demo.SelectedBottle.Content = mixture;
|
GlobalScene.Demo.SelectedBottle.Content = mixture;
|
||||||
mixture.Container = GlobalScene.Demo.SelectedBottle;
|
mixture.Container = GlobalScene.Demo.SelectedBottle;
|
||||||
|
GlobalScene.Demo.SelectedBottle.BuildMenu();
|
||||||
Visible = false;
|
Visible = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,87 +0,0 @@
|
|||||||
[gd_scene load_steps=6 format=3 uid="uid://br78rurjakp3a"]
|
|
||||||
|
|
||||||
[ext_resource type="Script" path="res://Scenes/VirtualChemDemo.cs" id="1_aartk"]
|
|
||||||
[ext_resource type="PackedScene" uid="uid://re3bwidsx0do" path="res://Scenes/MainControlPanel.tscn" id="2_cfpbe"]
|
|
||||||
[ext_resource type="PackedScene" uid="uid://u7apjw1vvak3" path="res://Scenes/Bottle.tscn" id="2_ei0nr"]
|
|
||||||
[ext_resource type="PackedScene" uid="uid://bde5n0vfm6jvs" path="res://Scenes/Flask.tscn" id="3_p6s6c"]
|
|
||||||
[ext_resource type="PackedScene" uid="uid://cubdalatqln4x" path="res://Scenes/StringLoader.tscn" id="5_5y6ld"]
|
|
||||||
|
|
||||||
[node name="VicrtualChemDemo" type="Node2D"]
|
|
||||||
script = ExtResource("1_aartk")
|
|
||||||
|
|
||||||
[node name="VBoxContainer" type="VBoxContainer" parent="."]
|
|
||||||
offset_right = 40.0
|
|
||||||
offset_bottom = 40.0
|
|
||||||
|
|
||||||
[node name="HSeparator" type="HSeparator" parent="VBoxContainer"]
|
|
||||||
layout_mode = 2
|
|
||||||
|
|
||||||
[node name="MainControlPanel" parent="VBoxContainer" instance=ExtResource("2_cfpbe")]
|
|
||||||
layout_mode = 2
|
|
||||||
|
|
||||||
[node name="HSeparator2" type="HSeparator" parent="VBoxContainer"]
|
|
||||||
layout_mode = 2
|
|
||||||
|
|
||||||
[node name="Potions" type="HBoxContainer" parent="."]
|
|
||||||
offset_left = 70.0
|
|
||||||
offset_top = 553.0
|
|
||||||
offset_right = 670.0
|
|
||||||
offset_bottom = 621.0
|
|
||||||
|
|
||||||
[node name="Prev" type="Button" parent="Potions"]
|
|
||||||
layout_mode = 2
|
|
||||||
text = "<-"
|
|
||||||
|
|
||||||
[node name="Items" type="HBoxContainer" parent="Potions"]
|
|
||||||
layout_mode = 2
|
|
||||||
|
|
||||||
[node name="MenusButton" parent="Potions/Items" instance=ExtResource("2_ei0nr")]
|
|
||||||
layout_mode = 2
|
|
||||||
|
|
||||||
[node name="Bottle" parent="Potions/Items" instance=ExtResource("2_ei0nr")]
|
|
||||||
layout_mode = 2
|
|
||||||
|
|
||||||
[node name="Bottle2" parent="Potions/Items" instance=ExtResource("2_ei0nr")]
|
|
||||||
layout_mode = 2
|
|
||||||
|
|
||||||
[node name="Bottle3" parent="Potions/Items" instance=ExtResource("2_ei0nr")]
|
|
||||||
layout_mode = 2
|
|
||||||
|
|
||||||
[node name="Bottle4" parent="Potions/Items" instance=ExtResource("2_ei0nr")]
|
|
||||||
layout_mode = 2
|
|
||||||
|
|
||||||
[node name="Bottle5" parent="Potions/Items" instance=ExtResource("2_ei0nr")]
|
|
||||||
layout_mode = 2
|
|
||||||
|
|
||||||
[node name="Bottle6" parent="Potions/Items" instance=ExtResource("2_ei0nr")]
|
|
||||||
layout_mode = 2
|
|
||||||
|
|
||||||
[node name="Bottle7" parent="Potions/Items" instance=ExtResource("2_ei0nr")]
|
|
||||||
layout_mode = 2
|
|
||||||
|
|
||||||
[node name="Next" type="Button" parent="Potions"]
|
|
||||||
layout_mode = 2
|
|
||||||
text = "->"
|
|
||||||
|
|
||||||
[node name="Flask" parent="." instance=ExtResource("3_p6s6c")]
|
|
||||||
offset_left = 747.0
|
|
||||||
offset_top = 57.0
|
|
||||||
offset_right = 875.0
|
|
||||||
offset_bottom = 569.0
|
|
||||||
|
|
||||||
[node name="HRepr" type="HBoxContainer" parent="."]
|
|
||||||
offset_left = 32.0
|
|
||||||
offset_top = 272.0
|
|
||||||
offset_right = 702.0
|
|
||||||
offset_bottom = 352.0
|
|
||||||
|
|
||||||
[node name="Label" type="Label" parent="HRepr"]
|
|
||||||
layout_mode = 2
|
|
||||||
text = "Full Expression"
|
|
||||||
|
|
||||||
[node name="FullRepr" type="RichTextLabel" parent="HRepr"]
|
|
||||||
custom_minimum_size = Vector2(550, 80)
|
|
||||||
layout_mode = 2
|
|
||||||
|
|
||||||
[node name="ExpressionLoader" parent="." instance=ExtResource("5_5y6ld")]
|
|
||||||
position = Vector2i(250, 200)
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using Godot;
|
using Godot;
|
||||||
|
|
||||||
public partial class VirtualChemDemo : Node2D
|
public partial class VirtualChemistryDemo : Node2D
|
||||||
{
|
{
|
||||||
public Flask Flask { get; set; }
|
public Flask Flask { get; set; }
|
||||||
public RichTextLabel FullRepr { get; set; }
|
public RichTextLabel FullRepr { get; set; }
|
||||||
71
Tests/Line2d.cs
Normal file
71
Tests/Line2d.cs
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
using Godot;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
public partial class Line2d : Line2D
|
||||||
|
{
|
||||||
|
private TestScene Test { get; set; }
|
||||||
|
public Vector2 Start => Test.A.Position;
|
||||||
|
public Vector2 End => Test.B.Position;
|
||||||
|
public float CurveRate { get; set; } = 20;
|
||||||
|
public int CDir { get; set; } = 1;
|
||||||
|
|
||||||
|
private void MakeCurve(float curveRate=20f, int cDir = 1)
|
||||||
|
{
|
||||||
|
Vector2[] xs = new Vector2[17];
|
||||||
|
int[] x2 = new[] { 4, 12 };
|
||||||
|
int[] x3 = new[] { 2, 6, 10, 14};
|
||||||
|
int[] x4 = new[] { 1, 3, 5, 7, 9, 11, 13, 15 };
|
||||||
|
Vector2 vd = End - Start;
|
||||||
|
Vector2 nor = vd.Rotated(Mathf.Pi / 2 * cDir);
|
||||||
|
Vector2 center = vd / 2 + 4f * nor / curveRate;
|
||||||
|
xs[0] = Start;
|
||||||
|
xs[16] = End;
|
||||||
|
xs[8] = center + xs[0];
|
||||||
|
foreach (int i in x2)
|
||||||
|
{
|
||||||
|
Vector2 v = xs[i + 4] - xs[i - 4];
|
||||||
|
Vector2 n = v.Rotated(Mathf.Pi / 2 * cDir);
|
||||||
|
Vector2 w = v / 2 + 2f * n / curveRate;
|
||||||
|
xs[i] = w + xs[i - 4];
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (int i in x3)
|
||||||
|
{
|
||||||
|
Vector2 v = xs[i + 2] - xs[i - 2];
|
||||||
|
Vector2 n = v.Rotated(Mathf.Pi / 2 * cDir);
|
||||||
|
Vector2 w = v / 2 + n / curveRate;
|
||||||
|
xs[i] = w + xs[i - 2];
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (int i in x4)
|
||||||
|
{
|
||||||
|
Vector2 v = xs[i + 1] - xs[i - 1];
|
||||||
|
Vector2 n = v.Rotated(Mathf.Pi / 2 * cDir);
|
||||||
|
Vector2 w = v / 2 + n / curveRate;
|
||||||
|
xs[i] = w + xs[i - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
Points = xs;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void T()
|
||||||
|
{
|
||||||
|
Points = new[] { new Vector2(1, 1), new Vector2(2, 3) };
|
||||||
|
GD.Print(Points.Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called when the node enters the scene tree for the first time.
|
||||||
|
public override void _Ready()
|
||||||
|
{
|
||||||
|
Test = GetParent<TestScene>();
|
||||||
|
|
||||||
|
GD.Print("Ready");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||||
|
public override void _Process(double delta)
|
||||||
|
{
|
||||||
|
//T();
|
||||||
|
MakeCurve(CurveRate, CDir);
|
||||||
|
}
|
||||||
|
}
|
||||||
12
Tests/Test2.cs
Normal file
12
Tests/Test2.cs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
using Godot;
|
||||||
|
|
||||||
|
public partial class Test2 : Node2D
|
||||||
|
{
|
||||||
|
public override void _Ready()
|
||||||
|
{
|
||||||
|
GD.Print("READY ddd");
|
||||||
|
}
|
||||||
|
public override void _Process(double delta)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
37
Tests/TestScene.cs
Normal file
37
Tests/TestScene.cs
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
using Godot;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
public partial class TestScene : Node2D
|
||||||
|
{
|
||||||
|
public Marker2D A { get; set; }
|
||||||
|
public Marker2D B { get; set; }
|
||||||
|
|
||||||
|
public Line2d L1 { get; set; }
|
||||||
|
|
||||||
|
public Line2d L2 { get; set; }
|
||||||
|
public Line2d L3 { get; set; }
|
||||||
|
public Line2d L4 { get; set; }
|
||||||
|
// Called when the node enters the scene tree for the first time.
|
||||||
|
public override void _Ready()
|
||||||
|
{
|
||||||
|
A = GetNode<Marker2D>("A");
|
||||||
|
B = GetNode<Marker2D>("B");
|
||||||
|
L1 = GetNode<Line2d>("L1");
|
||||||
|
L2 = GetNode<Line2d>("L2");
|
||||||
|
L3 = GetNode<Line2d>("L3");
|
||||||
|
L4 = GetNode<Line2d>("L4");
|
||||||
|
L1.CurveRate = 20;
|
||||||
|
L1.CDir = 1;
|
||||||
|
L2.CurveRate = 10;
|
||||||
|
L1.CDir = 1;
|
||||||
|
L3.CurveRate = 10;
|
||||||
|
L3.CDir = -1;
|
||||||
|
L4.CurveRate = 20;
|
||||||
|
L4.CDir = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||||
|
public override void _Process(double delta)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user