• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Liutauras Vilda
  • Campbell Ritchie
  • Tim Cooke
  • Bear Bibeault
  • Devaka Cooray
Sheriffs:
  • Jeanne Boyarsky
  • Knute Snortum
  • Junilu Lacar
Saloon Keepers:
  • Tim Moores
  • Ganesh Patekar
  • Stephan van Hulst
  • Pete Letkeman
  • Carey Brown
Bartenders:
  • Tim Holloway
  • Ron McLeod
  • Vijitha Kumara

Making an object change direction when reaching a destination  RSS feed

 
Greenhorn
Posts: 16
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
[I am very new to coding and my aim is to make and object (a lorry) change destination when it reaches the first one (site). As for now, the lorry leaves its original place (concrete plant) and moves to the first site created. The user can add sites with mousePress (I used an array of sites). But then my lorry gets stuck on the first site and doesn't go to the next one. I also want the lorry to go to 2 sites and then come back to the concrete plant to then again leave for 2 sites etc... Can somebody help me, I am desperate and my deadline is next Monday.

I have attached my script, but simple version of it is as follows (pictures replaced by ellipses and rectangles):


 
Saloon Keeper
Posts: 4760
52
Eclipse IDE Firefox Browser Java MySQL Database VI Editor Windows
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Any reason that you are using floating point for you coordinates and vectors? Could you do it with int's?

In Java you almost never use the 'float' data type. Use 'double' instead.

Comparing floating point values for equality is iffy because of rounding errors. This, for example, may not give you the result you expect:
What is dir.normalize()?

Class member variables should be declared 'private' and getters provided only if necessary.

The Move() method name should start with a lower case.

Where is 'velocity' used?

If you've arrived at your destination the dest.x - loc.x will be zero.
 
Lilly Deel
Greenhorn
Posts: 16
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have use PVector because as I understand if I use int I will need to set location, concretePlant coordinates location.x = xCoord, location.y = yCoord etc... and PVector seems to make it possible to get these coordinate together in the brackets for easy reading? But maybe I am wrong. Should I change the PVectors to int then and write all coordinates like location.x etc?

I have changed float to double now, still does the same.

dir.normalize() is to make the vector a unit, which coordinates will be used to make the lorry move to the site. I tried using velocity like with the other examples but that just makes it go in any direction. I don't know how to implement the velocity along with the direction vector.

I don't understand the 'private' and getters. Does it mean I need to write Private in front of the class?

I have change Move() to move()


The idea behind the reachDestination function is to tell the lorry that when it reaches the destination, then it needs to go to the next site. But it doesn't work. Is there a better way to do it? I was thinking maybe instead of making it automatically go to the next sit, maybe the mousePress function can also make it go to the next site?

 
Carey Brown
Saloon Keeper
Posts: 4760
52
Eclipse IDE Firefox Browser Java MySQL Database VI Editor Windows
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Lilly Deel wrote:I have use PVector because as I understand if I use int I will need to set location, concretePlant coordinates location.x = xCoord, location.y = yCoord etc... and PVector seems to make it possible to get these coordinate together in the brackets for easy reading? But maybe I am wrong. Should I change the PVectors to int then and write all coordinates like location.x etc?

Unless there is a compelling reason to use floating point, don't. Yes, changing location.x = xCoord, would be preferred over using floating point. Is there an int version of PVector? You'd have to consider how normalize() should work if you are using int's.

I have changed float to double now, still does the same.

I wouldn't expect anything to change in the way of behavior.

dir.normalize() is to make the vector a unit, which coordinates will be used to make the lorry move to the site. I tried using velocity like with the other examples but that just makes it go in any direction. I don't know how to implement the velocity along with the direction vector.

If you are moving horizontal, vertical, or diagonal (45degrees) then integer is easy. If you are moving in any arbitrary angle then you might be stuck with floating point, in which case you may need both a locationFloat.x and a locationInt.x because the float may not fall exactly on a integer grid, e.g. pixels.

I don't understand the 'private' and getters. Does it mean I need to write Private in front of the class?

Example:
If you need to access this outside of the class then you'd need a getter...
Perhaps this is not critical yet but it is the proper object oriented approach.

The idea behind the reachDestination function is to tell the lorry that when it reaches the destination, then it needs to go to the next site. But it doesn't work.

As I mentioned, using '==' to compare floating point values doesn't always work because of rounding errors. This would be a non-issue if you use int for your vector type.

Is there a better way to do it? I was thinking maybe instead of making it automatically go to the next sit, maybe the mousePress function can also make it go to the next site?

I can't quite tell, the small amount of code you posted doesn't give me the big picture and I can't compile it and run it myself.
 
Lilly Deel
Greenhorn
Posts: 16
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator


Unless there is a compelling reason to use floating point, don't. Yes, changing location.x = xCoord, would be preferred over using floating point. Is there an int version of PVector? You'd have to consider how normalize() should work if you are using int's.


So I have changed my Lorry class to this ( I will take care of the private and public thingy later):



But now the lorry doesn't move.


If you are moving horizontal, vertical, or diagonal (45degrees) then integer is easy. If you are moving in any arbitrary angle then you might be stuck with floating point, in which case you may need both a locationFloat.x and a locationInt.x because the float may not fall exactly on a integer grid, e.g. pixels.


I'm moving towards the site that has been created randomly on the screen. So i cannot fix an angle. I do not understand how to use the location.Float.x and locationInt.x.


I can't quite tell, the small amount of code you posted doesn't give me the big picture and I can't compile it and run it myself.


Is there a way I can send you my whole script so you can have a better look? I'm trying to send it as a zip because you need the picture in the data folder and the two classes bu it won't let me.

Thank you very much for your help. I need it very much!
 
Carey Brown
Saloon Keeper
Posts: 4760
52
Eclipse IDE Firefox Browser Java MySQL Database VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

I'm moving towards the site that has been created randomly on the screen. So i cannot fix an angle.

Ah, this is what I was trying to determine but couldn't from the code. So, you won't be able to use integers for your location. However you'll need to convert to an int when you need a pixel  location, as in "(int)location.x". Your site has been arrived at by using the mouse to click on a pixel, so this is NOT floating point. To see if you're at the destination you'd need
I saw a hint that your "lorry" is drawn in a 60x60 pixel square. Is this correct? If so, then you would need to know if you've arrived somewhere inside those bounds. Yes? Is the site coordinate the center of the 60x60 area or the upper left corner?
 
Carey Brown
Saloon Keeper
Posts: 4760
52
Eclipse IDE Firefox Browser Java MySQL Database VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
How many lines of code are we talking? you should be able to post ~500 lines or so with no problem.

Where does PVector come from?
 
Rancher
Posts: 2833
96
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
A (not THE!) problem might be that the move of the lorry is always of length 1, since it is a normalized vector. That means that if lorry is updated 50 times a second, you would move the lorry only 50 picels across. How many tines per second is lorry updated?

As Carey says, we have only a few snippets of your code. Is it possoible to show the whole code, including your PVector class? The snippets look allright to me, but I can't tell if what happens is all correct. Can you, in the updateLorry, print out the values of the updates? If these are 0 for some reason, that would explain why the lorrty doesn't move. Or maybe all new destinations have the same location as the very first one?
 
Lilly Deel
Greenhorn
Posts: 16
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have made it work!
So as you rightfully said Carey my problem were that the location was never = desrination most probably because of the float. So I've changed it to say that instead of = I have set it as if it reaches 1pixel from it and now it works
What I have posted was the whole script.
I'll post the new version tomorrow morning (it is 00:27 here in UK).
Thank you for you help! Might be back soon for the rest.
 
Lilly Deel
Greenhorn
Posts: 16
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
So this is the new script that makes my lorry goes to every site in the order:
 
Sheriff
Posts: 12343
201
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Lilly Deel wrote:I have made it work! ... So I've changed it to say that instead of = I have set it as if it reaches 1pixel from it and now it works


I have a pretty good idea of how you did this but I'd like you to consider a different way of "making it work".

This is the code you wrote:

And I'm betting you did something like this to "fix" it:

While something like this will "work," it's not really the cleanest way to code it. Here is one way it can be progressively cleaned up:

First, clarify the code by replacing the formula with a method call. This eliminates some of the noise created by the detailed calculations and improves the noise-to-signal ratio of your code.

Next, recognize that you still have a formula in the if-statement condition. You also have a method, distanceBetween(), that would be better assigned to the PVector class. So you refactor (Extract + Rename) some more to get something like this:

And now in the PVector class you'll have something like this:

Then, clean up some more by extracting more detailed calculation into a separate method, leaving a method call that clarifies the intent of the code:

Finally, I would rename the reachDestination() method to make it communicate its intent better:

Compare the readability of this refactored code to what you have written. Which version is easier to understand?

Line 50 above can still be improved by using an Iterator instead. I'll show you how that can be done after you've had some time to digest the refactoring steps I illustrated here.
 
Junilu Lacar
Sheriff
Posts: 12343
201
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I just realized that you may not be able to change the PVector class if it's the Android processing.core.PVector. If that's the case, just go back over my last examples and replace any reference to PVector with a user-defined class like Point or something like that.

         
 
Junilu Lacar
Sheriff
Posts: 12343
201
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

I wrote:I have a pretty good idea of how you did this but I'd like you to consider a different way of "making it work".


I was close enough... I didn't see the new code you posted until after I posted my reply (one of the perils of being long-winded)
 
Junilu Lacar
Sheriff
Posts: 12343
201
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You wrote this:

You could make this code much more readable if you refactored it to something like this:

And you could define a Route class to encapsulate the logic for managing the list of sites:

The point of all these examples I'm giving is to show that you can restructure your code (what's called "refactoring") so that it's easier to read and more logically organized. Refactoring improves the design of your program by eliminating code smells like duplication and misplaced responsibilities and makes your program easier to maintain and modify.
 
Marshal
Posts: 60136
188
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Carey Brown wrote:. . . the float may not fall exactly on a integer grid, e.g. pixels. . . .

That applies to the current app which appears to use Swing, but in JavaFX locations are denominated as double pairs.

OP: I think you need to turn your screen off and work with pencil paper and eraser. Make sure to get a large eraser; you will need it. Work out the algorithm for getting your lorry from the cement factory to the site, presumably with the drum still turning and before the concrete sets solid What is going to happen if you encounter an obstruction? Consider the information you need in the lorry object. Forget about pictures and fonts; you can add them later. Just get the lorry working.
 
Lilly Deel
Greenhorn
Posts: 16
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

The point of all these examples I'm giving is to show that you can restructure your code (what's called "refactoring") so that it's easier to read and more logically organized. Refactoring improves the design of your program by eliminating code smells like duplication and misplaced responsibilities and makes your program easier to maintain and modify.


I do really appreciate this. Especially that this is for a coursework to hand in, making it readable is definitely what I am trying to do. I will add your obs

Work out the algorithm for getting your lorry from the cement factory to the site, presumably with the drum still turning and before the concrete sets solid  What is going to happen if you encounter an obstruction? Consider the information you need in the lorry object. Forget about pictures and fonts; you can add them later. Just get the lorry working.


For now my lorry is just an image that moves on the screen. I don't know how I can make it as an actual lorry with the drum turning etc..
I like the idea of adding some considerations into it such as meeting an obstruction etc. But i feel that with the limited time I have and all the extra requirements I have to finish this I will not have time to look at it.

I think you need to turn your screen off and work with pencil paper and eraser. Make sure to get a large eraser; you will need it. 


I agree, I need to take a step back and work out what I want to do with this to help me come up with an algorithm.

What my lecturer wants to see is: to have a script with a logical structure, that there is a reason behind it, and if possible that it interacts with HTML, external libraries or external data.

So this is my scope:

The goal: Monitoring and optimization of a concrete delivery service for construction sites by the company operator (concrete plant and truck suppliers).

I should have a concrete plant, two trucks ( I will need to add another) and several sites that are created thanks to the user's click.
The operator can have at any time the vision of the trucks of his company that deliver concrete to the worksites located in a given geographical area. And the number of sites evolves (= click of the user hard the screen).

A construction site awaiting delivery = a certain logo (current one). A site delivered becomes a logo of a house.
A truck can deliver up to two jobs without returning to the company to replenish.

Delivery procedure: Placing a site on the screen triggers the delivery. It will be done with the 1st truck available and still having concrete (not having already delivered two sites)

A truck will therefore deliver under 3 conditions:
     1 / The truck must not be reserved. The program scans in ascending numerical order trucks to choose the 1st available ie not already reserved. A truck is not booked when it is at the company or when it has finished delivering its concrete. (Reserved truck R = 1, Truck available R = 0)
     2 / The truck still has concrete: it did not deliver 2 sites. Its number of sites delivered N is 0 or 1
When a truck returns to the company, R and N are reset to 0. When the truck has finished delivering, the R is reset to 0 and the N is incremented by +1. But he can not deliver to a site that has already been delivered.
    3 / the choice of the truck closest to the site could be added as the third criterion.
If possible, we can put a delay of 3 '' for example to simulate the delivery?

If we do not show new sites at the end of delivery, the truck returns to the company.

Going Further: Accumulate the distance traveled by the trucks, which will allow the operator to know the transport cost (by multiplying by a cost / unit of distance).

So hopefully from this set I can maybe write down how I will manage to do this. If you already have ideas of functions to which I can move for each step it would be great for me to go faster as i don't know much about the language and the function and it will help me save time in the research part. I do appreciate it might be a lot though so any kind of help will be appreciated
 
Lilly Deel
Greenhorn
Posts: 16
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ok so I have set out what my variables are and the actions for better understanding.

Variables:
Concrete plant -> Coordinates (xCoord, yCoord) + size;
Site(arraylist) -> Coordinates (site.x, site.y or destination.x, destination.y in the lorry class) + size;
Lorry (x2) -> Coordinates (location.x, location.y); size; origin; destination.

Actions of a lorry:
move to a site (1)
go to the next site of the list (2)
go back to the concrete plant after it reaches 2 sites
go to the next site (3), then (4), go back to concrete plant etc...

(basically it does 2 sites and comes back, 2 site and comes back etc... And it cannot go to a site that has already been delivered).


Choice of the lorry: (to make it a bit more complex). I got 2 lorries and the choice on which lorry to go needs to be made by:
if its free (not already on route to a site);
if it is full (has done 0 or 1 site, or hasn't done 2 sites);
the closest one ( measure the distance).

Interaction with html: I was thinking if possible to somehow measure the distance made by each lorries and display it on the html screen (and save the data with a keypress if possible).

So I started by looking if I can maybe add a lorry (don't know if its the right part to start on, maybe the actions would be better). And i tried telling it that if the siteNumber is under 2 it goes through the list of sites, but if not the new destination is the concrete plant. Buuut it doesn't work...

Here's the class lorry (I havent changed the other class and the main script):
 
Campbell Ritchie
Marshal
Posts: 60136
188
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Why are such locations part of the Lorry class? A Lorry doesn't have vectors; it has wheels, engine, speed, direction, etc. It might have a journey to travel and you can argue that a journey has a start point and a destination point, in which case I would say that vector is a bad name for a location. From those points it should be possible to work out a speed and direction. You can get away with not implementing wheels or engine at this stage, but a load might be a good idea. Denominate the load in tons, so you start off with two tons and deliver one ton to each destination.
I don't understand why you are using vectors to represent a location and a speed from the same class.
Give your lorry a starting point for its journey and a finishing point and work out its speed and direction. One starting point and one finishing point. That is all you have to do at present. Work out how far it will move per second or whatever interval you are using. Then get it to print the locations it passes through. Get that working, without pictures or GUI or anything. When you get that working, see if you can't 1 px short of the destination. Then work out how to go from that destination to the second delivery and then how to go back home to the factory. Maybe after the 1st delivery youi change the start to the delivery point and the destination becomes the 2nd delivery point. When you have a lot of points printed going round that triangle, then consider putting the GUI back.
Are you using a Swing Timer on the GUI? I think you don't need a timer without the GUI. Just imagine the factory is at (123, 456) and the first delivery at (789, 1011). Then you want a series of numbers starting (123, 456) or maybe (124, 457) and ending at (789, 1011), etc. You may need some maths to work out the speed. In that case direction = arc tan((789 − 123) ÷ (1011 − 456)) and lToRSpeed = speed × cos(direction) and downToUpSpeed = speed × sin(direction). At least I think that is right; if you get ridiculous results try up and down reversed. There are methods in the Math class which will help work out the complicated formulae for you (use atan2 not atan), but read their details carefully. They return doubles, for one thing.
 
Lilly Deel
Greenhorn
Posts: 16
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
What are 1ToRSpeed and downToUpSpeed?
 
Lilly Deel
Greenhorn
Posts: 16
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Oh never mind, I just realised it is not a 1 but l. So its the speed in the x and y direction then?
Here's my new script for the lorry class. However now it doesn't show anything on the screen:
 
Campbell Ritchie
Marshal
Posts: 60136
188
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Lilly Deel wrote:What are 1ToRSpeed and downToUpSpeed?

How fast you go from 1 l (=left) to R (=right) and from down to up. If you travel at 100mph in the direction of 45° (=0.5π) you will be going approx 70.71mph downwards and 70.71mph to the right.
 
Lilly Deel
Greenhorn
Posts: 16
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Do you know how I can prevent the site to be created only when there's a mousePressed (and stay on the background)? Because for now there's a site created automatically at the beginning even without mousePressed.
 
Campbell Ritchie
Marshal
Posts: 60136
188
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
That appears to have been addressed in your other thread.

I think you should sort out one problem at a time. Have you got your lorry moving yet?
 
Lilly Deel
Greenhorn
Posts: 16
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Sadly no... I am very bad at this..

So I went back to the code that was working and tried adding my conditions by saying that a lorry is selected when:
  • The truck that is the nearest (by checking the distance);
    If the truck as enough cement (each lorry start with 2 units (u), and everytime it goes to a site, it looses 1 unit. When it reaches 0 it needs to go back to the concrete plant to "fill up")
    If it is not already delivering (deliv).


  • And the when the lorry is set as available, it must execute the "move" function.
    I have made some print lines to see if it is ever selected and it seems to be, but the lorries don't move.

     
    Campbell Ritchie
    Marshal
    Posts: 60136
    188
    • Likes 1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator

    Lilly Deel wrote:. . . a lorry is selected when:

  • The truck that is the nearest (by checking the distance);
  • . . .

    Please don't try to run before you can walk. Create a situation with one lorry, one starting point, and one destination. Once that is working add a second destination. Then work out how to go home to the cement works.
    Once you have got that working, consider multiple lorries. Consider calculating distances. Consider obstacle avoidance. But not until after you have the simple scenario working.
     
    Lilly Deel
    Greenhorn
    Posts: 16
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Trying to change Lorry class so that the lorry moves.
    However when I try changing the location to a boolean rather than PVector (and int doesn't work either), it tell me that "the primitive tupe double of location does not have a field x".
     
    Campbell Ritchie
    Marshal
    Posts: 60136
    188
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Don't change anything. Start from scratch. Stop guessing about what types should be; there is no way you can make a boolean into a location. Maybe you should start with a Location class. Make it well encapsulated and follow the rules of object‑oriented class writing.
     
    Carey Brown
    Saloon Keeper
    Posts: 4760
    52
    Eclipse IDE Firefox Browser Java MySQL Database VI Editor Windows
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Is this an Android app? I'm not familiar with the flow.

    Presumably the draw() method is a special name that the framework knows to call. Your draw() method draws the concrete plant and sites but not the lorry(?). The Lorry class has a displayLorry() method, which doesn't strike me as a name the framework would be looking for. 'displayLorry()' is called from the Lorry's update() method, but I would expect to see some timer driven event to cause that method to be called and I don't see evidence of that. The draw() method may know where to draw the elements because it's a recognized name. Does displayLorry() know where to draw the Lorry?

    In general, it seems to me that, before getting into the logic of lorries, plants, and sites, that you should have started with a very simple program that moves a rectangle across the screen. That way you could work out the kinks with much simpler code.
     
    Campbell Ritchie
    Marshal
    Posts: 60136
    188
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator

    Carey Brown wrote:. . . you should have started with a very simple program that moves a rectangle across the screen. . . .

    I would start even simpler. Simply print out the coordinates you would be at every minute/second during the journey. Start by simply moving horizontally or vertically, so only one coordinate changes and there isn't any complicated arithmetic.
     
    • Post Reply Bookmark Topic Watch Topic
    • New Topic
    Boost this thread!