How to make collision work with userData in Tiled? (LigGDX) - arrays

currently i'm trying to figure out how to make collision detection work with libgdx and tiled. I collect all bodies from tiled inside an Array
this is the code where i take the bodies from tiled and store them inside an array:
public static Array<Body> parseTiledObjectLayer(World world, MapObjects mapObjects, int layerValue) {
switch (layerValue) {
case 0:
Array<Body> groundBodies = new Array<Body>();
for (MapObject mapObject : mapObjects) {
Shape shape;
if (mapObject instanceof PolylineMapObject) {
shape = createPolyline((PolylineMapObject) mapObject);
} else if (mapObject instanceof RectangleMapObject) {
shape = createRectangle((RectangleMapObject) mapObject);
} else if (mapObject instanceof PolygonMapObject) {
shape = createPolygon((PolygonMapObject) mapObject);
} else {
continue;
}
Body body;
BodyDef bodyDef = new BodyDef();
bodyDef.type = BodyDef.BodyType.StaticBody;
body = world.createBody(bodyDef);
body.createFixture(shape, 0);
groundBodies.add(body);
shape.dispose();
}
return groundBodies;
case 1:
Array<Body> objectBodies = new Array<Body>();
for (MapObject mapObject : mapObjects) {
Shape shape;
if (mapObject instanceof PolylineMapObject) {
shape = createPolyline((PolylineMapObject) mapObject);
} else if (mapObject instanceof RectangleMapObject) {
shape = createRectangle((RectangleMapObject) mapObject);
} else if (mapObject instanceof PolygonMapObject) {
shape = createPolygon((PolygonMapObject) mapObject);
} else {
continue;
}
Body body;
BodyDef bodyDef = new BodyDef();
bodyDef.type = BodyDef.BodyType.StaticBody;
body = world.createBody(bodyDef);
FixtureDef fixtureDef = new FixtureDef();
fixtureDef.shape = shape;
body.createFixture(shape, 0);
objectBodies.add(body);
shape.dispose();
}
return objectBodies;
default: //if default returns null we don't have to return null outside the switch loop and if we return something
//inside a switch statement we don't use the statement break;
return null;
}
}
Now in another class i return the static array to collect the information from it and in this other class i also implement ContactListener.
In this variable i retrieve the above static array:
private Array<Body> objectBodies = MapLoader.parseTiledObjectLayer(world, map.getLayers().get(1).getObjects(), 1);
objectBodies.get(1).setUserData("Object");
and here i also try to assign a UserData for collision.
Now here i actually try to check if there is collision:
#Override
public void beginContact(Contact contact) {
Fixture body1;
Fixture body2;
if(contact.getFixtureA().getUserData() == "Player"){
body1 = contact.getFixtureA();
body2 = contact.getFixtureB();
} else {
body1 = contact.getFixtureB();
body2 = contact.getFixtureA();
}
if(body1.getUserData() == "Player" && body2.getUserData() == "Object"){
System.out.println("collided");
}
}
Everything seems fine but for some reason when Player and Object collide nothing seems to be happening. I don't have this error when setting the userdata inside the static method. Any help appriciated.

Related

System.IndexOutOfRangeException in c# window form

I have been trying too parse 2 parameter using for loop but it only loop once and locates one parameter. This is my code.
By providing rectangle 70,80 command in the form, I am trying to draw shapes but while passing through check variable for loop works only once. It does not increments but returns value only after first execution then goes to check number of parameter then rejects with error Array out of bounds.
public String[] ParameterSplit;
public IDictionary<string, int> VariableDictionary = new Dictionary<string, int>();
public IDictionary<string, int> MethodVariableDictionary = new Dictionary<string, int>();
public Boolean AlreadyInArray = false;
public Boolean Value1IsVariable = false;
public Boolean Value2IsVariable = false;
public int value = 0;
public int value1 = 0;
public int value2 = 0;
public CommandParser()
{
}
//This method is used for the validation of commands and parameters which passes thorough
//singleline command and multiline command method
public string[] CommandParsers(string input, int lineCount)
{
string[] text = { };
string[] inputcommand = input.Split(',', ' ');
if (inputcommand[0].ToUpper() == "MOVETO")
{
if(inputcommand.Length < 4)
{
Convert.ToInt32(inputcommand[1]);
Convert.ToInt32(inputcommand[2]);
text = inputcommand;
}
}
else
{
if (inputcommand[0].ToUpper() == "DRAWTO")
{
if (inputcommand.Length == 3)
{
Convert.ToInt32(inputcommand[1]);
Convert.ToInt32(inputcommand[2]);
text = inputcommand;
}
else
{
MessageBox.Show($"ERROR: Provide correct parameter for moveto in line no {lineCount}");
string[] strings = { "moveto,100,100" };
text = strings;
}
}
else if (inputcommand[0].ToUpper() == "RECTANGLE")
{
ParameterSplit = inputcommand[1].Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
CheckForVariable();
if (ParameterSplit.Length == 2)
{
}
else
{
Convert.ToInt32(ParameterSplit[0]);
Convert.ToInt32(ParameterSplit[1]);
text = ParameterSplit;
}
}
else if (inputcommand[0].ToUpper() == "CIRCLE")
{
if (inputcommand.Length == 2)
{
Convert.ToInt32(inputcommand[1]);
text = inputcommand;
}
else
{
MessageBox.Show("ERROR: Provide correct parameter for circle in line no " + lineCount );
string[] strings = { "circle,20" };
text = strings;
}
}
else if (inputcommand[0].ToUpper() == "TRIANGLE")
{
if (inputcommand.Length == 3)
{
Convert.ToInt32(inputcommand[1]);
Convert.ToInt32(inputcommand[2]);
text = inputcommand;
}
else
{
MessageBox.Show("ERROR: Provide correct parameter for triangle in line no "+ lineCount);
string[] strings = { "triangle,20,60" };
text = strings;
}
}
else if (inputcommand[0].ToUpper() == "PEN")
{
Pen = true;
string[] validateinput = { "pen", inputcommand[1] };
text = validateinput;
switch (inputcommand[1])
{
case "red":
color = Color.Red;
break;
case "blue":
color = Color.Blue;
break;
case "yellow":
color = Color.Yellow;
break;
case "green":
color = Color.Green;
break;
case "violet":
color = Color.Violet;
break;
}
}
else if (inputcommand[0].ToUpper() == "FILL")
{
string[] validateinput = { "fill", inputcommand[1] };
text = validateinput;
switch (inputcommand[1])
{
case "on":
fill = true;
break;
case "off":
fill = false;
break;
}
}
else if (inputcommand.Length > 2)
{
text = inputcommand;
//checks if the middle element is a "="
if(inputcommand[1].ToUpper() == "=")
{
//check if the variable is already stored or not
//StoreVarialable();
foreach(KeyValuePair<string,int> variable in VariableDictionary)
{
if (variable.Key.Equals(inputcommand[0]))
{
AlreadyInArray = true;
}
}
foreach(KeyValuePair<string,int> variable in VariableDictionary)
{
if(variable.Key.Equals(inputcommand[2]))
{
value1 = variable.Value;
Value1IsVariable = true;
}
}
if(inputcommand.Length.Equals(5))
{
foreach(KeyValuePair<string,int> variable in VariableDictionary)
{
if (variable.Key.Equals(inputcommand[4]))
{
value2 = variable.Value;
Value2IsVariable = true;
}
}
if (AlreadyInArray)
{
VariableDictionary.Remove(inputcommand[0]);
}
}
try
{
if (Value1IsVariable.Equals(false))
{
value1 = Convert.ToInt32(inputcommand[2]);
}
if (Value2IsVariable.Equals(false))
{
if (inputcommand.Length.Equals(5))
{
value2 = Convert.ToInt32(inputcommand[4]);
}
}
if (inputcommand.Length > 3)
{
if (inputcommand[3].Equals("+"))
{
value = value1 + value2;
}
else if (inputcommand[3].Equals("-"))
{
value = value1 - value2;
}
else
{
//InvalidOperator();
}
}
else
{
try
{
value = int.Parse(inputcommand[2]);
}
catch (FormatException ex)
{
//If it is not an integer throw an error
//ValueIsIncorrect();
}
}
//Adds the variable with the inputted value if it is an integer
// VariableDictionary.Add(inputcommand[0], value);
}
catch (FormatException ex)
{
//If it is not an integer throw an error
//ValueIsIncorrect();
//return;
}
}
else
{
}
}
else
{
string[] validateinput = { "error" };
text = validateinput;
}
//end of condition
}
return text;
}
public void CheckForVariable()
{
//Loops through all the parameters
for (int i = 0; i<ParameterSplit.Length ; i++)
{
int index = i;
try
{
//Checks if the parameter is an int
int test = int.Parse(ParameterSplit[index]);
}
catch
{
Boolean foundVariable = false;
foreach (KeyValuePair<string, int> variable in MethodVariableDictionary)
{
if (variable.Key.Equals(ParameterSplit[index]))
{
//if it is then assign the parameter the integer value of the variable
ParameterSplit[index] = variable.Value.ToString();
//ErrorList = ErrorList + variable.Key + ParameterSplit[i] + Environment.NewLine; ;
foundVariable = true;
}
}
if (foundVariable == false)
{
//if it is not then loop through the VariableDictionary to check if the parameter is a variable name
foreach (KeyValuePair<string, int> variable in VariableDictionary)
{
if (variable.Key.Equals(ParameterSplit[i]))
{
//if it is then assign the parameter the integer value of the variable
ParameterSplit[i] = variable.Value.ToString();
}
}
}
}
}
}
//This method is used to get the color from pen by returning its values
internal Color getColor()
{
return color;
}
}
I tried this where I have to check 2 parameter using for loop inside CheckForVariable method

How do I map Stream<List<double>> to List<double> in Dart Flutter

We are trying to cast a Stream<List> to List in Dart Flutter.
List<double> _DeadliftWeightsList(QuerySnapshot snapshot){
List <Weights?> weights = snapshot.docs.map((doc){
Weights(
date: doc.get('date') ?? DateTime.now(),
weight: doc.get('deadLiftWeight') ?? 0);
}).toList();
final List<double> normalized = NormalizedData(weights);
return normalized;}
List<double> DLWeights() {
List <double> weights = [];
usersCollection.snapshots()
.map(_DeadliftWeightsList).listen((List<double> weights1) {
weights = weights1;
});
return weights;}
This is our Return List Function
List<double> returnList (String key){
List<double> values = [];
if(key == "Dead Lift"){
values = DLWeights();
}
else if (key == "Back Squat"){
values = BSWeights();
}
else if (key == "Hip Thrust") {
values = HTWeights();
}
else if (key == "Leg Press") {
values = LPWeights();
}
else if (key == "Bench Press") {
values = BPWeights();
}
else if (key == "Lateral Pulldown ") {
values = LateralPDWeights();
}
else if (key == "Bicep Curl") {
values = BCWeights();
}
else if (key == "Tricep Extension") {
values = TEWeights();
}
return values;
}
These functions are meant to grab the data from the Stream and return a list. However it is not grabbing the data and is giving us a bad state error.
Here is a short example of how you can convert a Stream<List<double>> to a List<double>:
Stream<List<double>> listOfDoubleStream() async* {
for (int i = 1; i <= 100; i++) {
yield [i.toDouble()];
}
}
Future<void> main() async {
List<double> result = await listOfDoubleStream().expand((e) => e).toList();
print(result);
}
The expand method is equivalent to flatMap in some other languages. Calling expand allows you to convert Stream<List<double>> to a Stream<double>, and then calling toList will get you the List<double>.
Another approach would be to use collection-for and the spread operator ... :
List<double> result = [
await for (final item in listOfDoubleStream()) ...item,
];

Unity3D: How to go Back or Forward in Array list

I have a gameObject with an ID, the gameObjects are spawned by giving initial ID: 1 , then any after spawned will be +1 so next is ID: 2.
I have two buttons that check current gameObjects ID#, BackOneButton (-1) and PlusOneButton (+1).
Currently it works but only if the array of gameObjects have IDs in order like for example [gameObject-ID:1], [gameObject-ID:2], [gameObject-ID:3]
But since you can self destruct a certain gameObject, here is where the error is --->
Now the array is not in order for example [gameObject-ID:1], [gameObject-ID:3], [gameObject-ID:4]. So if I'm currently in [gameObject-ID:3] and I use the BackOneButton and looks for ID: 2 it won't find it BUT there is ID:1. That's my error, I can't seem to figure out how to handle this.
Basically, How do I handle missing increments and skip over the missing?
Left Button (MinusOneButton)
void ButtonAction_LeftMinusOne()
{
// Get list of all gameObjects and -1 current to switch
string objName = manager.currentObjectTransform.name;
string[] splitArray = objName.Split('_');
string idObjNumber = splitArray[1];
switch (idObjNumber)
{
case "0":
// not supposed to be ID: 0
break;
case "1":
// nothing to go back to, this is ID: 1
break;
default:
// currently in (ID: 2 & Up) second object
int currentID = int.Parse(idObjNumber);
string idBackOne = (currentID - 1).ToString();
GameObject[] allObjInFull = GameObject.FindGameObjectsWithTag("Object");
if (allObjInFull.Length >= 2)
{
for (int i = 0; i < allObjInFull.Length; i++)
{
if (allObjInFull[i].transform.name.Contains(idBackOne))
{
// Set Camera
camera.transform.parent = allObjInFull[i].transform.GetChild(0).GetChild(1);
camera.transform.position = allObjInFull[i].transform.GetChild(0).GetChild(1).position;
camera.transform.rotation = allObjInFull[i].transform.GetChild(0).GetChild(1).rotation;
}
}
}
break;
}
}
Right Button (PlusOneButton)
void ButtonAction_RightPlusOne()
{
// Get list of all objects and +1 current to switch
string objName = manager.currentObjectTransform.name;
string[] splitArray = objName.Split('_');
string idObjNumber = splitArray[1];
switch (idObjNumber)
{
case "0":
// not supposed to be ID: 0
break;
default:
// currently in (ID: 1 & Up) object
int currentID = int.Parse(idObjNumber);
string idPlusOne = (currentID + 1).ToString();
GameObject[] allObjInFull = GameObject.FindGameObjectsWithTag("Object");
if (allObjInFull.Length >= 2)
{
for (int i = 0; i < allObjInFull.Length; i++)
{
if (allObjInFull[i].transform.name.Contains(idPlusOne))
{
// Set Camera
camera.transform.parent = allObjInFull[i].transform.GetChild(0).GetChild(1);
camera.transform.position = allObjInFull[i].transform.GetChild(0).GetChild(1).position;
camera.transform.rotation = allObjInFull[i].transform.GetChild(0).GetChild(1).rotation;
}
}
}
break;
}
}
It would be way better (especially regarding maintenance) and more efficient to have a central manager class with a List<GameObject> where you simply Add and Remove items dynamically. (Since you already seem to have one in manager I would rather extend that one)
public static class ObjectsManager
{
// If you are not concerned about
// capsulation you could ofcourse make this public as well
// but I thought this is cleaner
private static List<GameObject> objects;
// Read-only property
public static int Count
{
get
{
Initialize();
return objects.Count;
}
}
// initialize the list once
// I first had this in e.g. Awake
// but now you can easily use this in multiple scenes
public static void Initialize(bool force reinitialize = false)
{
if(objects != null && ! reinitialize) return;
objects = FindObjectsWithTag("Object").ToList();
}
public static void Add(GameObject newObject)
{
Initialize();
if(objects.Contains(newObject) return;
objects.Add(newObject);
}
public static void Destroy(GameObject toDestroy)
{
Initialize();
if(objects.Contains(toDestroy)
{
objects.Remove(toDestroy);
}
Object.Destroy(toDestroy);
}
public static int IndexOf(GameObject obj)
{
Initialize();
return objects.IndexOf(obj);
}
public static GameObject GetByIndex(int index)
{
Initialize();
// Use modulo to wrap around the index in case
// +1 or -1 exceeds the list ends
// in your case you might not need it
// but I decided to add it to be more flexible
var nextIndex = (index + 1) % objects.Count;
return objects[index];
}
}
Everytime you Instantiate a new object make sure to also call
ObjectsManager.Add(newObject);
and everytime where you destroy an object rather use
ObjectsManager.Destroy(objectToDestroy);
so it is also removed from the list first.
Then you can easily use
var currentIndex = ObjectsManager.IndexOf(certainObject);
to get the current index of an object and simply move through the index (+1, -1)
var nextObject = ObjectsManager.GetByIndex(currentIndex + 1);
var lastObject = Objects manager.GetByIndex(currentIndex - 1);
In case you switch the scene you have reinitialize the list once in order to get rid of null references
ObjectsManager.Initialize(true);
In your example code you would e.g. use something like
void ButtonAction_LeftMinusOne()
{
GameObject currentObject = manager.currentObjectTransform.gameObject;
int currentIndex = ObjectsManager.IndexOf(currentObject);
if(currentIndex < 0)
{
Debug.LogErrorFormat(this, "Object {0} is not in list!", currentObject.name);
return;
}
if(currentIndex == 0)
{
// nothing to do go back to
// Except you want wrap around then simply remove this check
Debug.Log("Already is first object in list", this);
return;
}
GameObject newObject = ObjectsManager.GetByIndex(currentIndex - 1);
Transform childOfNewObject = newObject.GetChild(0).GetChild(1);
// Set Camera
// Using simply SetParent with parameter worldPositionStays=false
// reduces it to one single call
camera.transform.SetParent( childOfNewObject, false);
}
And accordingly
void ButtonAction_RightPlusOne()
{
GameObject currentObject = manager.currentObjectTransform.gameObject;
int currentIndex = ObjectsManager.IndexOf(currentObject);
if(currentIndex < 0)
{
Debug.LogErrorFormat(this, "Object {0} is not in list!", currentObject.name);
return;
}
if(currentIndex == ObjectsManager.Count - 1)
{
// nothing to do go forward to
// Except you want wrap around then simply remove this check
Debug.Log("Already is last object in list", this);
return;
}
GameObject newObject = ObjectsManager.GetByIndex(currentIndex + 1);
Transform childOfNewObject = newObject.GetChild(0).GetChild(1);
// Set Camera
// Using simply SetParent with parameter worldPositionStays=false
// reduces it to one single call
camera.transform.SetParent( childOfNewObject, false);
}

Use Kinect to create a digital catalog application

I am creating a WPF application to create digital catalog using kinect v1.8. I am trying to track only a single skeleton using following code:-
private void SensorSkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs skeletonFrameReadyEventArgs)
{
// Even though we un-register all our event handlers when the sensor
// changes, there may still be an event for the old sensor in the queue
// due to the way the KinectSensor delivers events. So check again here.
if (this.KinectSensor != sender)
{
return;
}
SkeletonFrame skeletonFrame = skeletonFrameReadyEventArgs.OpenSkeletonFrame();
if (skeletonFrame == null)
return;
Skeleton[] skeletons = new Skeleton[skeletonFrame.SkeletonArrayLength];
skeletonFrame.CopySkeletonDataTo(skeletons);
Skeleton skeleton = (from skl in skeletons
where skl.TrackingState == SkeletonTrackingState.Tracked
select skl).FirstOrDefault();
if (skeleton == null)
return;
Skeleton[] s = new Skeleton[1];
s[0] = skeleton;
if (SkeletonTrackingState.Tracked == s[0].TrackingState)
{
//s1.SkeletonStream.ChooseSkeletons(s[0].TrackingId);
var accelerometerReading = this.KinectSensor.AccelerometerGetCurrentReading();
this.interactionStream.ProcessSkeleton(s, accelerometerReading, skeletonFrame.Timestamp);
}
}
I am getting an exception when I run the code and skeleton gets detected as follows:-
on the line "this.interactionStream.ProcessSkeleton(s, accelerometerReading, skeletonFrame.Timestamp);"
I need to detect only one skeleton and use it for further processing like to access the digital catalog applications.
Thanks in advance.
I have Faced Same Problem By using below code I have track only one skeleton Which is closer to the sensor.and directly assign the closest skeleton to the main skeleton stream.
private void SensorSkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs skeletonFrameReadyEventArgs)
{
Skeleton[] skeletons = new Skeleton[0];
using (SkeletonFrame skeletonFrame = skeletonFrameReadyEventArgs.OpenSkeletonFrame())
{
if (skeletonFrame != null && this.skeletons != null)
{
//Console.WriteLine(skeletonFrame.SkeletonArrayLength);
skeletons = new Skeleton[skeletonFrame.SkeletonArrayLength];
// Set skeleton datas from skeletonFrame
skeletonFrame.CopySkeletonDataTo(this.skeletons);
TrackClosestSkeleton();
Skeleton[] singleSkeleton = new Skeleton[6];
Skeleton skl=(from mno in this.skeletons where mno.TrackingState==SkeletonTrackingState.Tracked && mno.TrackingId==globalClosestID select mno).FirstOrDefault();
if (skl == null)
return;
//Creating an empty skkeleton
Skeleton emptySkeleton = new Skeleton();
singleSkeleton[0] = skl; //Pass the Tracked skeleton with closestID
singleSkeleton[1] = emptySkeleton; //Passing Empty Skeleton
singleSkeleton[2] = emptySkeleton; //Passing Empty Skeleton
singleSkeleton[3] = emptySkeleton; //Passing Empty Skeleton
singleSkeleton[4] = emptySkeleton; //Passing Empty Skeleton
singleSkeleton[5] = emptySkeleton; //Passing Empty Skeleton
this.snew.SkeletonStream.ChooseSkeletons(globalClosestID);
var accelerometerReading = this.KinectSensor.AccelerometerGetCurrentReading();
this.interactionStream.ProcessSkeleton(singleSkeleton, accelerometerReading, skeletonFrame.Timestamp);
}
}
}
int globalClosestID = 0;
private void TrackClosestSkeleton()
{
if (this.snew != null && this.snew.SkeletonStream != null)
{
if (!this.snew.SkeletonStream.AppChoosesSkeletons)
{
this.snew.SkeletonStream.AppChoosesSkeletons = true; // Ensure AppChoosesSkeletons is set
}
float closestDistance = 10000f; // Start with a far enough distance
int closestID = 0;
foreach (Skeleton skeleton in this.skeletons.Where(s => s.TrackingState != SkeletonTrackingState.NotTracked))
{
if (skeleton.Position.Z < closestDistance)
{
closestID = skeleton.TrackingId;
closestDistance = skeleton.Position.Z;
}
}
if (closestID > 0)
{
this.snew.SkeletonStream.ChooseSkeletons(closestID); // Track this skeleton
globalClosestID = closestID;
}
}
}
check the above code it works for me.It may helpful to you.Here snew is the Kinectsensor.
You should try to track the closest skeleton using this method from MSDN
private void TrackClosestSkeleton()
{
if (this.kinect != null && this.kinect.SkeletonStream != null)
{
if (!this.kinect.SkeletonStream.AppChoosesSkeletons)
{
this.kinect.SkeletonStream.AppChoosesSkeletons = true; // Ensure AppChoosesSkeletons is set
}
float closestDistance = 10000f; // Start with a far enough distance
int closestID = 0;
foreach (Skeleton skeleton in this.skeletonData.Where(s => s.TrackingState != SkeletonTrackingState.NotTracked))
{
if (skeleton.Position.Z < closestDistance)
{
closestID = skeleton.TrackingId;
closestDistance = skeleton.Position.Z;
}
}
if (closestID > 0)
{
this.kinect.SkeletonStream.ChooseSkeletons(closestID); // Track this skeleton
}
}
}
And then in your SkeletonFrameReady
private void SkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)
{
Skeleton[] skeletons = new Skeleton[0];
using (SkeletonFrame skeletonFrame = e.OpenSkeletonFrame())
{
if (skeletonFrame != null && this.skeletonData != null)
{
skeletons = new Skeleton[skeletonFrame.SkeletonArrayLength];
// Set skeleton datas from skeletonFrame
skeletonFrame.CopySkeletonDataTo(this.skeletonData);
TrackClosestSkeleton();
}
}
//Do some stuff here
}

core-plot Mixing CPTScatterPlotInterpolationCurved and CPTScatterPlotInterpolationLinear

I need to be able to draw sequential line segments that have the same Y Coordinate with CPTScatterPlotInterpolationLinear and ones that do not with CPTScatterPlotInterpolationCurved.
As CPTScatterPlotInterpolationCurved draws all lines curved. I am currently doing this by adding multiple plots.
public List<CorrectedGraphPoints> GetCorrectDataPoints(List<PointF> dataSource)
{
int lastIndex = 0;
bool shouldLoop = true;
CPTScatterPlotInterpolation interpolation = CPTScatterPlotInterpolation.Curved;
List<CorrectedGraphPoints> OuterList = new List<CorrectedGraphPoints> ();
if (dataSource [0].Y == dataSource [1].Y)
interpolation = CPTScatterPlotInterpolation.Linear;
while (lastIndex+1 != dataSource.Count) {
OuterList.Add (new CorrectedGraphPoints (interpolation));
while (shouldLoop)
{
OuterList[OuterList.Count -1].Add(dataSource[lastIndex]);
if ((lastIndex + 1) < dataSource.Count) {
if (interpolation == CPTScatterPlotInterpolation.Linear) {
if (dataSource [lastIndex].Y != dataSource [lastIndex + 1].Y) {
interpolation = CPTScatterPlotInterpolation.Curved;
shouldLoop = false;
break;
}
}
if (interpolation == CPTScatterPlotInterpolation.Curved) {
if (dataSource [lastIndex].Y == dataSource [lastIndex + 1].Y) {
interpolation = CPTScatterPlotInterpolation.Linear;
shouldLoop = false;
break;
}
}
}
else {
shouldLoop = false;
break;
}
if (shouldLoop)
lastIndex++;
}
shouldLoop = true;
}
return OuterList;
}
public class CorrectedGraphPoints
{
private List<PointF> points;
public List<PointF> Points { get { return points; } }
private CPTScatterPlotInterpolation interpolation;
public CPTScatterPlotInterpolation Interpolation { get { return interpolation; } }
public CorrectedGraphPoints(CPTScatterPlotInterpolation interpolation)
{
this.interpolation = interpolation;
points = new List<PointF> ();
}
public void Add(PointF point)
{
points.Add (point);
}
}
However creating multiple plots that use fill slows the app down tremendously. I was wondering if I could limit how much I do this? I haven't been able to find a way to change the interpolation for a section?? IS this an just an issue with core plot or is it something wrong with my logic or code?
Another possible solution would be to add additional points to your data to draw the curved sections. This would allow you to use only one plot. The number of additional points needed will depend on several factors including the size of the plot and the line style used to draw the line.

Resources