I'm working on a 2D physics engine for polygons. What troubles me is finding triangle-triangle intersection. I'm combining three points to make up the triangles (x1,y1), (x2,y2), (x3,y3) or points a, b, and c, which is done for both of the triangles.
How would I use the points to find if the two triangles are overlapping? Bonus points if you can find the location of the collision giving the direction they are traveling.
I finally got a decent algorithm that finds the closest path between two general triangles.
See the full C# code on GitHub and some highlights below
Geometry Classes
public readonly struct Triangle
{
public Vector2 A { get; }
public Vector2 B { get; }
public Vector2 C { get; }
public bool Contains(Vector2 point) { }
public Contact GetClosestPoints(Vector2 other) { }
public Contact GetClosestPoints(Side other) { }
public Contact GetClosestPoints(Triangle other) { }
}
public readonly struct Side
{
public Vector2 A { get; }
public Vector2 B { get; }
public bool Contains(Vector2 point) { }
public Contact GetClosestPoints(Vector2 other) { }
public Contact GetClosestPoints(Side other) { }
}
public readonly struct Line
{
public float A { get; }
public float B { get; }
public float C { get; }
public bool Contains(Vector2 point) { }
public Vector2 Project(Vector2 point) { }
}
public readonly struct Contact
{
public Contact(Vector2 source, Vector2 target)
{
Source = source;
Target = target;
}
public Vector2 Source { get; }
public Vector2 Target { get; }
public Vector2 Direction { get => { }; }
public float Distance { get => { }; }
public Contact Flip() => new Contact(Target, Source);
}
Algorithm
Finding the closest points between to triangles, involves the following steps
Find closest points of triangle A to each of the following 6 geometries from triangle B
Take each vertex of triangle B and find the closest point to triangle A
Find distances to each vertex of triangle A
Find distances to each side of triangle A.
The closest point might be on the side, or on one of the ends of the sides
Take each side of triangle B and find the closest point to triangle A
Find distances to each vertex of triangle A. The closest point might be on the side
or on one of the ends
Find distances of the ends of the sides to triangle A
Sort through each of the 6 distances and pick the smallest value
Match the smallest value to the geometry element.
Create a Contact object with the matching pair of closest points.
Related
I am currently having troubles with entity framework core.
The application I am developing is supposed to help users plan their next business year by increasing/decreasing the quantity of a service they want to provide in the next year.
Based on their input the "worth" of a service is distributed pro rata to other "mini-services" that are contained in the changed service.
To do so I load the affected entries of the main service and the "mini-services" from Database via a repository which then uses Entity Framework.
public IEnumerable<OpsDistributionEntry> FilteredOpsDistributionEntries(int catalogId, IEnumerable<OpsDistributionEntry> filterEntries)
{
return _context.OpsDistributionEntries.FromSqlRaw(
$"SELECT * FROM OpsDistributionEntries WHERE (Id IN (SELECT OpsEntriesId FROM DistributionCatalogOpsDistributionEntry WHERE CatalogsId = {catalogId}) " +
$"AND EntityId IN ({string.Join(",", filterEntries.Select(x => x.EntityId))}))").ToList();
}
I then map those database objects to my domain objects via constructor.
var opsDistributionEntries = new OpsDistributionEntriesFromDatabaseObjects(
_repository.FilteredOpsDistributionEntries(_distCatalogId, _filterEntries));
public class OpsDistributionEntriesFromDatabaseObjects : IOpsDistributionEntries
{
private readonly IOpsDistributionEntries _distribution;
public OpsDistributionEntriesFromDatabaseObjects(IEnumerable<DatabaseObjects.OpsDistributionEntry> distribution)
{
_distribution = new OpsDistributionEntries(distribution.Select(x => new OpsDistributionEntryFromDatabaseObject(x)));
}
public IEnumerator<IOpsDistributionEntry> GetEnumerator()
{
return _distribution.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
public class OpsDistributionEntryFromDatabaseObject : IOpsDistributionEntry
{
public OpsDistributionEntryFromDatabaseObject(DatabaseObjects.OpsDistributionEntry opsDistributionEntry)
: this(opsDistributionEntry.Id, opsDistributionEntry.TotalCases, opsDistributionEntry.TotalEffectiveWeight, opsDistributionEntry.Provide,
opsDistributionEntry.Freeze,
new OpsFromDatabaseObject(opsDistributionEntry.Entity),
new DrgDistributionsFromDatabaseObjects(opsDistributionEntry.DrgDistribution))
{
}
private OpsDistributionEntryFromDatabaseObject(int id, int totalCases, double totalEffectiveWeight, bool provide, bool freeze, IOps ops,
IDrgDistributions drgDistribution)
{
Id = id;
TotalCases = totalCases;
TotalEffectiveWeight = totalEffectiveWeight;
Provide = provide;
Freeze = freeze;
Ops = ops;
DrgDistribution = drgDistribution;
}
public int Id { get; }
public int TotalCases { get; }
public double TotalEffectiveWeight { get; }
public bool Provide { get; }
public bool Freeze { get; }
public IOps Ops { get; }
public IDrgDistributions DrgDistribution { get; }
}
public sealed class OpsFromDatabaseObject : IOps
{
public OpsFromDatabaseObject(DatabaseObjects.Ops ops) : this(ops.Id, ops.Code, ops.Description, ops.Year)
{
}
private OpsFromDatabaseObject(int id, string code, string description, int year)
{
Id = id;
Code = code;
Description = description;
Year = year;
}
public int Id { get; }
public string Code { get; }
public string Description { get; }
public int Year { get; }
}
I pass the database objects on to different levels, but finally every value is assigned and every possible navigation property is mapped to an domain object.
With those mapped domain objects I recalculate the new "worth" of the service and the correlated "mini-services".
After calculation I again map my Domain Objects to DatabaseObjects.
DatabaseObjects.OpsDistributionEntry ToDatabaseObject() => new DatabaseObjects.OpsDistributionEntry
{
Id = Id,
EntityId = Ops.Id,
Freeze = Freeze,
Provide = Provide,
TotalCases = TotalCases,
TotalEffectiveWeight = TotalEffectiveWeight,
DrgDistribution = DrgDistribution.Select(x => x.ToDatabaseObject()).ToImmutableList(),
};
When I want to add those "updated" Objects to the context via repository
public void UpdateDistributionEntries(IEnumerable<OpsDistributionEntry> opsDistributionEntries)
{
if (opsDistributionEntries == null) throw new ArgumentNullException(nameof(opsDistributionEntries));
_context.OpsDistributionEntries.UpdateRange(opsDistributionEntries);
}
I am getting an Error that the Entities I want to updated are already being tracked by Entity Framework.
After some debugging I think that EF is still tracking the database objects I loaded for mapping the domain objects. I just use the database objects to map values to the domain objects and do not store any reference for them (as far as I understand).
Can any of you maybe tell me why they are still being tracked even if they are "unreachable". Or am I thinking wrong? Might this be because of Lazy Loading?
I've been debugging for almost 14 hours now :D Please someone give me a hint :D
Many thanks in advance
I have a list of Student objects List<Student> allStudents from which I need to find out which student gained how much score per course and task using Java 8 stream API. I came across some older posts like this one but couldn't apply to my problem.
Below are my nested classes:
public class Student{
private long studentId;
private List<Course> courses;
public long getStudentId() {
return studentId;
}
public List<Course> getCourses() {
return courses;
}
}
public class Course{
private long courseId;
private List<Task> tasks;
public long getCourseId() {
return courseId;
}
public List<Task> getTasks() {
return tasks;
}
}
public class Task{
private long taskId;
private List<Assessment> assessments;
public long getTaskId() {
return taskId;
}
public List<Assessment> getAssessments() {
return assessments;
}
}
public class Assessment{
private String type;
private double score;
public String getType() {
return type;
}
public double getScore() {
return score;
}
}
Somehow multi level grouping couldn't work for me. Could anyone guide me on this ?
As you mentioned in the old question you referenced, can use the flat map approach where each nesting level is flat mapped down to the level required as follows:
Map<Triple<Long, Long, Long>, Double> result = allStudents.stream()
.flatMap(s -> s.getCourses().stream().map(
c -> ImmutableTuple.of(s.getStudentId(), c)))
.flatMap(sc -> sc.get().getTasks().stream().map(
t -> ImmutableTuple.of(sc.getFirst(), sc.get().getCourseId(), t)))
.flatMap(sct -> sct.get().getAssessments().stream().map(
a -> ImmutableTuple.of(sct.getFirst(), sct.getSecond(), sct.get().taskId, a.getScore())))
.collect(Collectors.groupingBy(
ImmutableQuadruple::remove,
Collectors.summingDouble(ImmutableQuadruple::get)
));
Note: This is using tuples from the typedtuples library
I am new to AutoFixture so I hope you can help. How do you set some properties in an object but leave others as the AutoFixture default - while using XUnit's [Theory] attribute and an AutoDataAttribute.
For example, in the contrived Airport example below based on Jason Robert's Pluralsight course, when setting the property (or the Airport object) e.g.
f.Customize<Mock<IAirport>>(c => c.Do(m => m.SetupGet(i => i.code).Returns("NOO")));
the other properties are often null, or I have to manually set them rather than letting AutoFixture do it. I would prefer to have cleaner code where the fixtureFactory sets all the properties for the Airport so that the V2 unit test only passed in a single Airport parameter.
So, within the fixtureFactory
How do you set MULTIPLE properties?
How does one use the default AutoFixture values rather than leaving the uninitialized values as
null?
Thanks!
using AutoFixture;
using AutoFixture.AutoMoq;
using AutoFixture.Xunit2;
using Moq;
using System;
using Xunit;
namespace AirportTesterWithAutoFixture
{
public interface IAirport
{
string city { get; set; }
string code { get; set; }
string country { get; set; }
string name { get; set; }
void CallAirTrafficControl();
}
public class Airport : IAirport
{
public string name { get; set; }
public string city { get; set; }
public string code { get; set; }
public string country { get; set; }
public Airport()
{
}
public Airport(string name, string code, string country, string city)
{
this.name = name;
this.code = code;
this.country = country;
this.city = city;
}
public void CallAirTrafficControl()
{
if (this.country.Equals("Canada") && this.code.StartsWith("Y"))
{
// Send "Bonjour!"();
}
else
{
throw new Exception("Invalid code for Canada");
}
}
}
public class UnitTest1
{
[Fact]
public void V1_Validate_ExceptionThrown_ForInvalidCanadianAirportCode()
{
var fixture = new Fixture();
var sut = fixture.Create<Airport>();
// Overwrite code and country with invalid setting for Canada.
sut.country = "Canada";
sut.code = "NOT";
Assert.ThrowsAny<Exception>(() => sut.CallAirTrafficControl());
}
[Theory]
[AutoMoqInvalidAirportDataAttribute]
public void V2_Validate_ExceptionThrown_ForInvalidCanadianAirportCode(IAirport sut, string name, string city)
{
Airport airport = new Airport(name, sut.code, sut.country, city);
Assert.ThrowsAny<Exception>(() => airport.CallAirTrafficControl());
}
}
// https://stackoverflow.com/questions/58998834/how-to-use-ifixture-buildt-with-automoqcustomization-when-t-is-an-interface
public class AutoMoqInvalidAirportDataAttribute : AutoDataAttribute
{
public static Func<IFixture> fixtureFactory = () =>
{
IFixture f = new Fixture().Customize(new AutoMoqCustomization());
f.RepeatCount = 5;
// How do you set MULTIPLE properties?
// How does one use the default AutoFixture values rather than leaving the uninitialized values as null?
// Can one pass a custom property used earlier in the Fixture creation process to another custom property used later?
f.Customize<Mock<IAirport>>(c => c.Do(m => m.SetupGet(i => i.code).Returns("NOT")));
return f;
};
public AutoMoqInvalidAirportDataAttribute() : base(fixtureFactory)
{
}
}
}
AutoFixture does not populate mock properties by default, but it can be done. These blog posts describe how to do it:
https://blog.ploeh.dk/2013/04/05/how-to-configure-automoq-to-set-up-all-properties/
https://blog.ploeh.dk/2013/04/08/how-to-automatically-populate-properties-with-automoq/
Author of AutoFixture does not recommend this approach, however, as he considers declaration of properties in interfaces a design smell.
I could not find the original discussion about this topic unfortunately, but it is hidden somewhere on StackOverflow in the comments. Maybe you will be able to find it if you go through Mark Seemann's profile.
I'm a newbie to Fluent Nhibernate (FNH) or NHibernate (or even ORMs) in general. I have a pet project that I'm using to learn FNH and I'm stuck with, what looks like a design issue. Its a basic Library Management System and I have objects like books, users, booksize(!) etc. For instance, I have a BookSize class and its manager BookSizesManager which hold a list of BookSize objects. Could please anyone advise me how to go about creating ClassMap for both of them such that my database (for testing purpose, say a SQLite database) would have only one table called 'BookSizes' and would list all the BookSize objects in BookSizeManager?
My current implementation is as followed and flawed as it produces two tables 1. BookSize 2. BookSizes (from BookSizeManager Map).
My BookSize Class
public class BookSize
{
public virtual string ID { get; set; }
public virtual string Name { get; set; }
public virtual double Length { get; set; }
public virtual double Width { get; set; }
}
Corresponding ClassMap
public class BookSizeMap : ClassMap<BookSize>
{
public BookSizeMap()
{
Id(x => x.ID);
Map(x => x.Name);
Map(x => x.Length);
Map(x => x.Width);
}
}
My BookSizesManager Class
public class BookSizesManager
{
public virtual string Id { get; set; }
private IList<BookSize> m_bookSizes = new List<BookSize>();
public virtual IList<BookSize> Items
{
get { return new ReadOnlyCollection<BookSize>(m_bookSizes); }
set { if(value != null) m_bookSizes = value; }
}
public virtual void Add(BookSize size)
{
if (size != null)
{
m_bookSizes.Add(size);
}
}// Also contains other unimplemented CRUD methods, but haven't listed them here to reduce 'noise'
}
Corresponding ClassMap
public class BookSizesManagerMap : ClassMap<BookSizesManager>
{
public BookSizesManagerMap()
{
Id(x => x.Id);
HasMany(x => x.Items)
.Cascade.All();
Table("BookSizes");
}
}
Any help is greatly appreciated. Thanks in advance.
i would get rid of BookSizesManager completly and use the session directly and specify the tablename explicitly
public class BookSizeMap : ClassMap<BookSize>
{
public BookSizeMap()
{
Table("BookSizes");
...
}
}
BookSizesManager.Add(booksize); becomes session.Save(booksize);
BookSizesManager.Get(booksizeId); becomes session.Get(booksizeId);
I've having trouble figuring out how to select based on a list in a many to many relationship.
I've created with entities-framework the following entities and many to many relationship (please correct me if I'm going about this wrong) :
public class Foo {
public int FooID { get; set; }
public string FooName { get; set; }
public virtual ICollection<FooBar> Foo_Bar { get; set; }
}
public class Bar {
public int BarID { get; set; }
public string BarName { get; set; }
public virtual ICollection<FooBar> Foo_Bar { get; set; }
}
public class FooBar {
public int FooBarID{ get; set; }
public virtual int BarID { get; set; }
public virtual int FooID { get; set; }
}
In my code my controller will receive a list of Foo and I need to find all the Bar with those foo ( both with only and with any )
I'm at a loss for where to start really... this is all I've come up with:
public PartialViewResult SearchAnyBar(List<Foo> foos) {
List<FooBar> foobars = _db.FooBar.Select(fb => fb).ToList<FooBar>();
List<Bar> searchedBars = new List<Bar>();
foreach (Foo f in foos)
{
foreach (FooBar fXb in foobars)
{
if (fXb.FooID == f.FooID)
{
searchedBars.Add(_db.Bar.Where(b => b.BarID == fXb.BarID).FirstOrDefault());
}
}
}
return PartialView("The View", searchBars);
}
This works for the grabbing any Bar however:
I'm pretty positive there's a much better way of doing this, is there a way to select based on a list instead of going about 2 foreach loop?
I'm not sure how to go about getting a list of Foos where the Foo has ALL the Bars and not just ANY.
Remove FooBar class.
Just create a public virtual ICollection<Foo> Foos {get;set;} in you Bar class
and a public virtual ICollection<Bar> Bars {get;set;} in your Foo Class
This will create a many to many relationship (with a relation table named [Foo-Bar] or something like that in your db... but who minds, you will be using objects).
then
any query :
var listOfFooId = <a list of Foo>.Select(m => m.FooId).ToList;
return _db.Bar.Where(m => m.Foos.Any(x => listOfFooId.Contains(x.FooId)));
not sure I understood well the "only" and "any", but if you have problems with the other query... ask.
Untested, but it looks like you just need a join here... Joining on all the Bars off of all the FooBars joined to the Foos passed in, right?
public PartialViewResult SearchAnyBar(List<Foo> foos) {
var bars = (from f in foos
join fb in _db.FooBars on f.Id equals fb.FooId
join b in _db.Bars on fb.BarId equals b.BarId
select b).ToList();
return PartialView("The View", bars);
}